第六篇:多表操作

from django.db import models


# Create your models here.

# 用了OneToOneField和ForeignKey,模型表的字段,后面会自定加_id
# ManyToManyField会自动创建第三张表
# *************重点
# 一对一的关系:OneToOneField
# 一对多的关系:ForeignKey
# 多对多的关系:ManyToManyField


class Publish(models.Model):
    # id如果不写,会自动生成,名字叫nid,并且自增
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)
    email = models.EmailField()


class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    # 数字类型
    sex = models.IntegerField()
    # 可以用ForeignKey,但是得设置唯一性约束,会报警告,不建议用,建议用OneToOneField
    # authordetail=models.ForeignKey(unique=True)
    # to='AuthorDetail'  加引号,这个表能找到就可以,不用引号,类必须在上面定义
    authordetail = models.OneToOneField(to='AuthorDetail', to_field='id')  # to_field表示自动关联到主键上

    def __str__(self):
        return self.name


class AuthorDetail(models.Model):
    id = models.AutoField(primary_key=True)
    phone = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)


class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to=Publish, to_field='id')
    #多对多的关系建立在哪里都可以,例如:一个作者可以写多本书,一本书可以由多个作者写
    authors = models.ManyToManyField(to=Author)

    def __str__(self):
        return self.name
models文件
import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day77.settings")
    import django

    django.setup()

    from app01.models import *

    # 一对多新增数据
    # 添加一本北京出版社出版的书
    # 第一种方式
    # ret=Book.objects.create(name='红楼梦',price=34.5,publish_id=1)
    # print(ret.name)
    # 第二种方式,存对象publish=出版社的对象,存到数据库,是一个id
    # publish=Publish.objects.get(id=1)
    # pk是主键,通过主键查找
    # publish=Publish.objects.get(pk=1)
    # publish = Publish.objects.filter(pk=2).first()
    # ret = Book.objects.create(name='西游记', price=34.5, publish=publish)
    # print(ret.name)
    # 一对多修改数据
    # book=Book.objects.get(pk=1)
    # # book.publish=出版社对象
    # book.publish_id=2
    # book.save()
    # 方式二
    # book=Book.objects.filter(pk=1).update(publish=出版社对象)
    # book=Book.objects.filter(pk=1).update(publish_id=1)
    # 多对多新增
    # 为红楼梦这本书新增一个叫lqz,egon的作者
    # lqz=Author.objects.filter(name='lqz').first()
    # egon=Author.objects.filter(name='egon').first()
    # book=Book.objects.filter(name='红楼梦').first()
    # # add 添加多个对象
    # book.authors.add(lqz,egon)
    # add添加作者id
    # book.authors.add(1,2)
    #删除 remove,可以传对象,可以传id,可以传多个,不要混着用
    # book.authors.remove(lqz)
    # book.authors.remove(2)
    # book.authors.remove(1,2)
    # clear清空所有
    # book.authors.clear()
    # set,先清空,在新增,要传一个列表,列表内可以是, id,也可以是对象
    # book.authors.set([lqz,])
    # ********这样不行,因为它打散了传过去了,相当于book.authors.set(lqz)
    # book.authors.set(*[lqz,])


    # lqz=Author.objects.filter(name='lqz')
    # print(type(lqz))
    from  django.db.models.query import QuerySet
# ***************************基于对象的跨表查询
    '''
    一对一
    正向   author---关联字段在author--->authordetail   ------>  按字段
    反向   authordetail------关联字段在author--->author  -----> 按表名小写
    
    '''
    # 查询lqz作者的手机号   正向查询
    # author=Author.objects.filter(name='lqz').first()
    # # author.authordetail 就是作者详情的对象
    # authordetail=author.authordetail
    # print(authordetail.phone)
#     查询地址是 :山东 的作者名字   反向查询
#     authordetail=AuthorDetail.objects.filter(addr='山东').first()
#     # authordetail.author  这是作者对象
#     author=authordetail.author
#     print(author.name)

    #一对多
    '''
    一对多
    正向   book---关联字段在book--->publish   ------>  按字段
    反向   publish------关联字段在book--->book  -----> 按表名小写_set.all()
    '''
    # 正向 查询红楼梦这本书的出版社邮箱
    # book=Book.objects.filter(name='红楼梦').first()
    # # book.publish  就是出版社对象
    # pulish=book.publish
    # print(pulish.email)
    # 反向  查询地址是北京 的出版社出版的图书
    # publish=Publish.objects.filter(addr='北京').first()
    # # publish.book_set.all()  拿出所有的图书
    # books=publish.book_set.all()
    # # 统计一下条数
    # books=publish.book_set.all().count()
    # print(books)

    '''
    多对多
    正向   book---关联字段在book--->author   ------>  按字段.all()
    反向   author------关联字段在book--->book  -----> 按表名小写_set.all()
    '''
    #查询红楼梦这本书所有的作者
    # book=Book.objects.filter(name='红楼梦').first()
    # book.authors.all()  #是所有的作者,是一个queryset对象,可以继续点
    # print(book.authors.all())

    # 查询lqz写的所有书
    # lqz=Author.objects.filter(name='lqz').first()
    # books=lqz.book_set.all()
    # print(books)

    # 连续跨表
    # 查询红楼梦这本书所有的作者的手机号
    # book=Book.objects.filter(name='红楼梦').first()
    # authors=book.authors.all()
    # for author in authors:
    #     authordetail=author.authordetail
    #     print(authordetail.phone)


    # ****************************基于对象的查询---是子查询也就是多次查询
    # ***************基于双下划线的查询*****
    # 一对一
    # 查询lqz作者的手机号   正向查询  跨表的话,按字段
    # 以author表作为基表
    # ret=Author.objects.filter(name='lqz').values('authordetail__phone')
    # print(ret)
    # 以authordetail作为基表 反向查询,按表名小写  跨表的话,用表名小写
    # ret=AuthorDetail.objects.filter(author__name='lqz').values('phone')
    # print(ret)
    # 查询lqz这个作者的性别和手机号
    # 正向
    # ret=Author.objects.filter(name='lqz').values('sex','authordetail__phone')
    # print(ret)
    # 查询手机号是13888888的作者性别
    # ret=Author.objects.filter(authordetail__phone='13888888').values('sex')
    # print(ret)
    # ret=AuthorDetail.objects.filter(phone='13888888').values('author__sex')
    # print(ret)
test文件

 

posted @ 2019-03-14 22:09  王苗鲁  阅读(102)  评论(0编辑  收藏  举报