1. 创建数据库
cmd终端 create database book01;
show tables;
2. 创建django项目 book01
settings配置
数据库设置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "book01", # cmd创建的数据库名称
"USER": "root", # 连接数据库的用户名
"PASSWORD": "123", # 连接数据库的密码
"HOST": "127.0.0.1", # 连接主机,默认本级
"PORT": 3306, # 端口 默认3306
}
}
静态文件配置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,"statics")
settings同级init.py
import pymysql
pymysql.install_as_MySQLdb()
models.py添加表关系
from django.db import models
# Create your models here.
class Author(models.Model):
# nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
au = models.OneToOneField(to="AuthorDetail",)
def __str__(self):
return self.name
class AuthorDetail(models.Model):
# nid = models.AutoField(primary_key=True)
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
def __str__(self):
return self.addr
class Publish(models.Model):
# nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
def __str__(self):
return self.name
class Book(models.Model):
# nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
publishes = models.ForeignKey(to="Publish",)
authors = models.ManyToManyField(to='Author',)
def __str__(self):
return self.title
#id 不写,默认递增主键 __str__方法返回可读懂对象
执行数据库同步指令
python manage.py makemigrations
python manage.py migrate
创建admin超级用户
python manage.py createsuperuser
输入用户名:wuchao
邮箱不用输 直接回车
输入密码:必须超过8位,并且别太简单
admin注册表结构
from django.contrib import admin
# Register your models here.
from app01 import models
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)
admin.site.register(models.Book)
查询逻辑
showbook表
models.Book.objects.all() 查询所有的书籍的queryset对象
for循环得到model对象
model 对象点字段得到具体的名称
根据多表查询查到作者的对象,for循环得到model对象
# 已知书籍名,查询出版社,正向
# obj = models.Book.objects.filter(title="大主宰").first()
# ph = obj.publishes.name
# 已知书籍名,查询作者,正向查询
# obj = models.Book.objects.filter(title="万剑道尊").first()
# ret = obj.authors.all() #<QuerySet [<Author: 邸宗超>, <Author: 韩星>, <Author: 李文宝>]>
# for i in ret:
# print(i.name)
# print(i.au.telephone) #连环查询,有对象,正向查询
在前端html中生成多对多的作者名字有三种书写格式
第一种
{% for author_obj in obj.authors.all %}
{{ author_obj.name }}
{% if forloop.last %}
{% else %}
,
{% endif %}
{% endfor %}
根据后端传的queryset对象循环得到model对象,再获得作者的queryset对象,后边的if判断是根据是否是最后一 个作者来判断谁否加逗号
第二种方法 在models.py的book类中再创建一个方法后端的实例对象点方法就是调用
#没有改变数据库相关字段,不用执行数据库同步指令
def get_author_name(self):
ret = self.authors.all()
au_list = []
for i in ret:
i.append(i.name)
return ",".join(au_list)
前端改为 <td>{{ book_obj.get_author_name }}</td> 因为book_obj就是书籍的实例化对象
第三种方法
def get_author_name(self):
return ",".join([i.name for i in self.authors.all()])
列表推导时一次搞定
添加书籍表
if request.method == "GET":
all_publish = models.Publish.objects.all()
all_author = models.Author.objects.all()
#分别后的出版社和作者的queryset对象
return render(request,"addbook.html",{"all_publish":all_publish,"all_author":all_author})
else:
#post请求
# authors = request.POST.get("authors")
# get方法只能获得一个值
authors = request.POST.getlist("authors")
"""
print(authors) 根据前端的name属性取值
['1', '3'] 得到所有提交的作者id
"""
data = request.POST.dict()
"""
print(data)
#{'csrfmiddlewaretoken': 'Opb8KW3rEZ4glfxwXZ8hmrxwRzINxNFYD8vWkDoCn0MY1YYZ67iR6j2VZl3tWkl6', 'title': '神马', 'price': '666.00', 'publishes_id': '2', 'publishDate': '2019-10-10', 'authors': '3'}
"""
#request.POST.dict() 看authors数据,当有多个值时,得到最后一个
#多对多时的数据出错
但是第一个值和最后一个值没有在book字段中,根据字典的删除出去这两个字段
data.pop("csrfmiddlewaretoken")
data.pop("authors")
"""
print(data)
{'title': '神马', 'price': '666.00', 'publishes': '1', 'publishDate': '2019-10-03'}
"""
new_book_obj = models.Book.objects.create(**data)
new_book_obj.authors.add(*authors)
分别添加书籍表和作者表相关数据
return redirect("showbook")
注意 book表添加数据时,前端的name属性时提交数据的,book表和出版社表关联存的数据存储时publishes对应对象,publishes_id 对应数字,而book表中没有作者的相关字段,在第三张表
post的相关方法
self.authors.all() 根据书籍的实例化对象获得作者所有的对象,后端all(),前端all 没有括号
request.POST.get("authors") 根据属性获得一个值,没有是None
request.POST.getlist("authors") 多对对关系中,获得所有提交的数据比如作者的所有提交的id