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
View Code

书籍表多对多作者表,产生一张表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'}]>

 

posted @ 2020-04-14 14:41  只会玩辅助  阅读(203)  评论(0编辑  收藏  举报