多表相关操作
三种关系 : 一对一 , 一对多 , 多对多
创建表
一对一:
xx = models.OneToOneField(to='表名',to_field='字段名',on_delete=models.CASCADE) # 级联删除,# to_field可以不写,默认是关联到另一张表的主键
一对多:
xx = models.ForeignKey(to='表名',to_field='字段名',on_delete=models.CASCADE)
多对多:
xx = models.ManyToManyField(to='表名',) # 自动创建第三张表
示例:
# 作者 <-一对一-> 作者信息
# 出版社 <-一对多-> 书籍 (外键加在多的表里面)
# 书籍 <-多对多-> 作者
# 作者表
class Author(models.Model): #比较常用的信息放到这个表里面
# nid = models.AutoField(primary_key=True) # id可以不写,默认会加上并设为主键
name=models.CharField( max_length=32)
age=models.IntegerField()
authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) # 一对一
def __str__(self):
return self.name
# 作者详细信息表(不常用的信息分到另一张表)
class AuthorDetail(models.Model):#不常用的放到这个表里面
# nid = models.AutoField(primary_key=True)
birthday=models.DateField()
# telephone = models.BigIntegerField()
telephone=models.CharField(max_length=32) # 方便后面模糊查询
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() # 实际上是CharField -- 数据字段验证,可以帮我们校验保存进来的数据是否为email格式的
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)
publishs=models.ForeignKey(to="Publish",on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author',) # authors这个属性自动创建第三张表,建立多对多关系 不会生成字段
def __str__(self):
return self.title
# 手动创建第三张表,连接书籍和作者多对多的关系(在orm中不方便使用,除非第三张表有自己独立的字段)
# class BookToAuthor(models.Model):
# book_id = models.ForeignKey(to='Book')
# author_id = models.ForeignKey(to='Author')
增删改查
增
# 1.增
# 1.1 一对一添加(作者表和作者信息表)
new_author_detail = models.AuthorDetail.objects.create(
birthday='1979-08-08',
telephone='13838383838',
addr='黑龙江哈尔滨'
)
obj = models.AuthorDetail.objects.filter(addr='山西临汾').first()
# 方式一
models.Author.objects.create(
name='王涛',
age=40,
authorDetail=new_author_detail # 放model对象 obj
)
# 方式二(常用)
models.Author.objects.create(
name='文洋',
age=41,
authorDetail_id=obj.id # 放 mysql字段名称
)
# 1.2 一对多添加(书籍表和出版社表)
# 方式一
obj = models.Publish.objects.get(id=2)
models.Book.objects.create(
title='小李的床头故事',
publishDate='2019-07-22',
price=3,
# publishs=models.Publish.objects.get(id=1), # model对象
publishs=obj, # model对象
)
# 方式二(常用)
models.Book.objects.create(
title='小李的床头故事2',
publishDate='2019-07-21',
price=3.5,
publishs_id=obj.id, # mysql字段
)
# 1.3 多对多添加(作者表和书籍表)
# 方式一(常用)
book_obj = models.Book.objects.get(id=1) # 找到书籍
book_obj.authors.add(*[1,2]) # 找到第三张表并直接添加作者id,多个值用*[,]
# 方式二
author1 = models.Author.objects.get(id=1) # 先找到2个作者
author2 = models.Author.objects.get(id=3)
book_obj = models.Book.objects.get(id=5) # 找到书籍
book_obj.authors.add(*[author1,author2])
删
一对一和一对多的删除和单表删除操作一样
# 一对一
models.AuthorDetail.objects.get(addr='山西运城').delete()
# 作者信息表删除信息,对应的作者也被级联删除了...
models.Author.objects.get(id=3).delete()
# 作者表删除信息,对应的作者信息不受影响!
# 通俗点就是: 我和你关联,你不能随便删,会影响我.但我可以随便删,我不影响你(追星??)
# 一对多(书籍表和出版社表)
models.Publish.objects.get(id=1).delete()
# 出版社表删除信息,对应出版的书也会一同删除
models.Book.objects.get(id=1).delete()
# 书籍表删除信息,对应的出版社不受影响
# 多对多(书籍表和作者表)
book_obj = models.Book.objects.get(id=6)
# book_obj.authors.remove(*[4,])
book_obj.authors.remove(*[4,6])
book_obj.authors.clear() # clear清空,全删的时候用
book_obj.authors.set('1') # 清空原来的记录,并重新添加(字符串)
book_obj.authors.set(['4','6'])
改
# 更新
# 一对一
models.Author.objects.filter(id=6).update(
name='崔老师',
age=16,
# authorDetail=models.AuthorDetail.objects.get(id=6)
authorDetail_id=4
)
# 一对多
models.Book.objects.filter(id=4).update(
# publishs=models.Publish.objects.get(id=3)
publishs_id=2
)
# 多对多
上面删除的set方法
# orm似乎没有级联更新的方法...
models.Publish.objects.filter(id=2).update(
id=4 # 报错!
)
零碎知识点
外部文件操作django的models:
# 外部文件使用django的models,需要配置django环境
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "singletablehw.settings")
import django
django.setup()
from app01 import models
.......
时区问题:
settings.py
USE_TZ = False
form表单中:
novalidate 去除浏览器帮忙做的事
python后端的url别名反向解析:
urls.py:
url(r'^lib/', views.lib, name='lib'),
url(r'^add_book/', views.add_book, name='add_book'),
views.py:
from django.urls import reverse # 做urls别名反向解析的
def add_book(request):
......
# return redirect(reverse('lib'))
return redirect('lib') # redirect里用别名解析不用写reverse,直接写别名 不带参数的
print(reverse('delete_book',arg=(71,))) # /delete_book/71/ 带参数的
前端html模板语法中的url别名反向解析:
<a href="{% url 'add_book' %}" class="btn btn-primary">添加书籍</a> # 无参数的
<a href="{% url 'edit_book' obj.id %}" class="btn btn-warning btn-sm">编辑</a> # 有参数的
查看mysql当前会话是否为严格模式
select @@sql_mode;
查看全局
select @@global.sql_mode;
使用django提供的admin:
1.执行manage.py createsuperuser指令,创建超级管理员
2.admin.py文件中注册要管理的表
from app01 import models
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)
admin.site.register(models.Book)
3.执行django项目,访问/admin/
主键简写 --- pk
(假设id为主键) id=4 --- pk=4