Django表设计,多表操作复习
1.settings文件配置数据库
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER':'root', 'PASSWORD':'root', 'HOST':'127.0.0.1', 'PORT':3306 } }
2.models.py 创建表(书籍表,出版社表,作者表,作者详情)
from django.db import models #基类 class BaseModel(models.Model): is_delete = models.BooleanField(default=False) #默认不是删除,数据库中是0/1 create_time = models.DateTimeField(auto_now_add=True) # 设置 abstract = True 来声明基表,作为基表的Model不能在数据库中形成对应的表 class Meta: abstract = True #声明该表只是一个抽象表不出现在数据库中 #书籍表 class Book(BaseModel): name = models.CharField(max_length=64) price = models.DecimalField(max_digits=5,decimal_places=2) img = models.ImageField(upload_to='img',default='default.jpg') #关联出版社表 publish = models.ForeignKey( to='Publish', #关联publish表 db_constraint=False, #断关联(断开Book表和Publish表的关联,方便删数据,虽然断开了关联但是还能正常使用) related_name='books',#反向查询字段:publish_obj.books就能查出当前出版社出版的的所有书籍 on_delete=models.DO_NOTHING,#设置连表操作关系 ) #关联作者表 authors = models.ManyToManyField( to='Author', db_constraint=True, #断开关联 related_name='books' #反向查询字段 ) class Meta: db_table='book' verbose_name='书籍' verbose_name_plural=verbose_name def __str__(self): return self.name #出版社表 class Publish(BaseModel): """name、address、is_delete、create_time""" name = models.CharField(max_length=64) addres = models.CharField(max_length=64) class Meta: db_table='publish' verbose_name='出版社' verbose_name_plural=verbose_name def __str__(self): return self.name #作者表 class Author(BaseModel): """name、age、is_delete、create_time""" name = models.CharField(max_length=64) age = models.IntegerField() class Meta: db_table = 'author' verbose_name='作者' verbose_name_plural=verbose_name def __str__(self): return self.name #作者详情 class AuthorDetail(BaseModel): """mobile, author、is_delete、create_time""" mobile = models.CharField(max_length=11) author = models.OneToOneField( to='Author', db_constraint=False, related_name='detail', on_delete=models.CASCADE ) class Meta: db_table='author_detail' verbose_name='作者详情' verbose_name_plural=verbose_name def __str__(self): return self.author.name
书籍表多对多作者表,产生一张表book_authors,所以一共是五张表
书籍表
1.publish_id是和出版社表一对多关联,在models.py中是写publish
2.书籍表关联作者表多对多,models.py写的是authors,但是在数据表中不会出现这个字段,会生成一张book_authors表
新生成的一张表book_authors
3.一对多字段增删改 (书籍表和出版社表)
增:create
删:delete
改:update
4.多对多字段增删改(书籍表和作者表)
增:add #先查询主键为2的书籍 book_obj = models.Book.objects.filter(pk=2).first() print(book_obj.authors) #对象点击多对多虚拟字段,会直接跨到多对多的第三张表 book_obj.authors.add(1) #传数字或者传对象,给书籍2增加主键为1的作者
book_obj.authors.add(2,3) #也可以一次性传入多个
删:remove book_obj=models.Book.objects.filter(pk=2).first() book_obj.authors.remove(1) #删除书籍2和作者1的数据 book_obj.authors.remove(2,3) #也可以删除多个,也可以传对象
改:set 修改的实质就是把不符合条件的数据删除,增加没有的数据 book_obj=models.Book.objects.filter(pk=2).first() book_obj.authors.set([1,]) #将主键为2的书籍表作者修改为1 book_obj.authors.set([2,3])
注意:set()内必须传递一个可迭代对象
5.查询(一对多,多对多,一对一)
基于双下划线查询
-正向:按字段,跨表可以在filter,也可以在values中
-反向:按表名小写,跨表可以在filter,也可以在values中
#一对一 #查询jason作者的手机号(正向查询) models.AuthorDetail.objects.filter(author__name='jason').values('mobile') #<QuerySet [{'mobile': '110'}]> #查询jason作者的手机号(反向查询) models.Author.objects.filter(name='jason').values('detail__mobile') #<QuerySet [{'detail__mobile': '110'}]> #查询jason这个作者的年龄和手机号 (正向查询) models.AuthorDetail.objects.filter(author__name='jason').values('mobile','author__age') #<QuerySet [{'mobile': '110', 'author__age': 12}]> #查询jason这个作者的年龄和手机号 (反向查询) Author name和age models.Author.objects.filter(name='jason').values('detail__mobile','age') #<QuerySet [{'detail__mobile': '110', 'age': 12}]> #查询书籍id是2的作者的电话号码 (跨多张表) models.Book.objects.filter(pk=2).values('authors__detail__mobile') #<QuerySet [{'authors__detail__mobile': '110'}]>
一对多和多对多都是这种查询方法
#多对多
查询书籍id是2的作者名
models.Book.objects.filter(pk=2).values('authors__name') #<QuerySet [{'authors__name': '33'}, {'authors__name': 'jason'}]>