Python Day 72 Django框架 图书管理系统回顾ORM 正向查询、反向查询、跨表查询、Django终端打印SQL语句、ORM十三个必会操作总结

  ##基础数据准备

#数据模板准备
  图书表、出版社、作者表、作者详情表、
#表之间的关系
  图书表 和 出版社 一对多
  图书表 和 作者表 多对多
  作者表 和 作者详情表 一对一 (这里专门把作者表拆成两张表来练习orm操作)
#细节
  1、
多对多字段建在查询频率比较高的那张表中
  2、多对多的字段只是一个虚拟字段、在数据库中不显示
    # 告诉django orm自动帮你创建第三张表
    # 查询的时候 可以借助该字段跨表
#要执行两条数据迁移命令:
python3 manage.py makemigrations
python3 manage.py migrate
fromdjango.dbimportmodels#Createyourmodelshere.fromdjango.confimportsettingsfromdjango.dbimportmodels#Createyourmodelshere.#图书表classBook(models.Model):title=models.CharField(max_length=32)price=models.CharField(max_length=32)publish_date=models.DateField(auto_now_add=True)#外键字段publish=models.ForeignKey(to='Publish')#多对多字段建在查询频率比较高的那张表中authors=models.ManyToManyField(to='Author')#authors只是一个虚拟字段#告诉djangoorm自动帮你创建第三张表#查询的时候可以借助该字段跨表def__str__(self):returnself.title#必须返回一个字符串类型否则直接报错#出版社classPublish(models.Model):name=models.CharField(max_length=32)addr=models.CharField(max_length=32)email=models.EmailField()def__str__(self):returnself.name#作者classAuthor(models.Model):name=models.CharField(max_length=32)age=models.CharField(max_length=32)#一对一字段也应该建在查询频率较高的表中author_detail=models.OneToOneField(to='AuthorDetail')def__str__(self):returnself.name#作者详情表classAuthorDetail(models.Model):phone=models.CharField(max_length=32)addr=models.CharField(max_length=32)def__str__(self):returnself.phone
models.py

  ##Django终端打印SQL语句

如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看
在Django项目的settings.py文件中,在最后复制粘贴如下代码:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上

补充:
除了配置外,还可以通过一点.query即可查看查询语句,注意只能是queryset对象

  ##怎样在Django项目中直接测试orm语句

#在app01目录下test.py文件
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day72.settings")#该句在manage.py文件中可以直接拷贝过来
    import django
    django.setup()  #手动配置完毕 便可以在下面进行测试

  ##ORM操作

from django.test import TestCase

# Create your tests here.
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day72.settings")
    import django
    django.setup()
    from app01 import models
    # 只有quertset对象才可以查看sql语句
    # print(models.Publish.objects.all().query)

    # (一对多表)外键字段的增删改查
    #
    # 传数字
    # models.Book.objects.create(title='红楼梦',price='199',publish_id=1)
    # 传对象
    # publish_obj = models.Publish.objects.filter(pk=2).first()
    # models.Book.objects.create(title='红楼梦',price='199',publish=publish_obj)

    # 修改
    # models.Book.objects.filter(pk=1).update(publish_id=3)
    # 传数字
    # publish_obj = models.Publish.objects.filter(pk=1).first()
    # # 传对象
    # models.Book.objects.filter(pk=2).update(publish=publish_obj)
    
    (多对多 第三张表) 外键字段的增删改查
    # add即可以传数字 也可以传对象  还支持传多个  单个单个的参数 不要传容器类型
    # book_obj = models.Book.objects.filter(pk=1).first()
    # # book_obj.authors.add(1) #跨到第三张表
    # author_obj = models.Author.objects.all()
    # book_obj.authors.add(*author_obj)
    #
    # author_list = models.Author.objects.all()
    # print(author_list)
    # book_obj.authors.add(*author_list)


    # remove
    # book_obj = models.Book.objects.filter(pk=1).first()
    # book_obj.authors.remove(1)
    # book_obj.authors.remove(2,3)
    # 放对象也可以

    # set
    # book_obj = models.Book.objects.filter(pk=1).first()
    # # book_obj.authors.set([1,])
    # author_list = models.Author.objects.all()
    # book_obj.authors.set(author_list)

    # clear
    # book_obj = models.Book.objects.filter(pk=1).first()
    # book_obj.authors.clear()  # 清空当前对象所对应的多对多关系

    """
    add
    remove
    set
    上面三个可以传一个或多个参数  并且即可以是数字也可以是对象
    clear
    不传参数 直接清空    
    """
    """
    正向
    
    反向
    
    # 正向与方向的概念解释

    # 一对一
    # 正向:author---关联字段在author表里--->authordetail        按字段
    # 反向:authordetail---关联字段在author表里--->author        按表名小写
        # 查询jason作者的手机号   正向查询
        # 查询地址是 :山东 的作者名字   反向查询
      
    # 一对多
    # 正向:book---关联字段在book表里--->publish        按字段
    # 反向:publish---关联字段在book表里--->book        按表名小写_set.all() 因为一个出版社对应着多个图书
    
    # 多对多
    # 正向:book---关联字段在book表里--->author        按字段
    # 反向:author---关联字段在book表里--->book        按表名小写_set.all() 因为一个作者对应着多个图书
    """
    # 基于对象的跨表查询  (都是子查询)
    # 1.查询书籍是红楼梦的出版社的名称
    # book_obj = models.Book.objects.filter(title='红楼梦').first()
    # print(book_obj.publish.name)
    # 2.查询东方出版社出版的所有的书
    # publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    # print(publish_obj.book_set)  # app01.Book.None
    # print(publish_obj.book_set.all())
    # 3.查询作者是jason的写过的所有的书
    # author_obj = models.Author.objects.filter(name='jason').first()
    # print(author_obj.book_set)  # app01.Book.None
    # print(author_obj.book_set.all())
    # 4.查询作者jason的住址
    # author_obj = models.Author.objects.filter(name='jason').first()
    # print(author_obj.author_detail.addr)
    # 5.查询手机号是110的作者姓名
    # author_detail = models.AuthorDetail.objects.filter(phone='110').first()
    # print(author_detail.author.age)

    """
    基于对象的反向查询 除了一对一直接点表名小写就可以拿到关联对象
    一对多个多对多反向都必须 表名小写_set
    """
    # 基于双下划线的跨表查询 (都是联表查询)
    # 1.查询书籍是红楼梦的出版社名称
    # res = models.Book.objects.filter(title='红楼梦').values('publish__name')
    # print(res)
    # 2.查询书籍是红楼梦的作者姓名
    # res = models.Book.objects.filter(title='红楼梦').values('authors__name','title')
    # print(res)
    # 3.查询作者jason的手机号
    # res = models.Author.objects.filter(name='jason').values('author_detail__phone')
    # print(res)
    # 4.查询书籍是红楼梦的作者的手机号
    # res = models.Book.objects.filter(title='红楼梦').values('authors__author_detail__phone')
    # print(res)

    # 反向查询
    # 1.查询出版社为东方出版社的所有图书的名字和价格
    # res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price','name')
    # print(res)(正查)
    # res1 = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
    # print(res1)(反查)

    # 2.查询作者姓名是jason的手机号
    # res = models.Author.objects.filter(name='jason').values('author_detail__phone')
    # print(res)(正查)
    # res1 = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
    # print(res1)(反查)


    # def func():
    #     pass
    # func.name = 'hahaha'
    # print(func.name)
test.py

  ##ORM十三个必会操作总结

#1、返回QuerySet对象的方法有
all()
filter()
exclude()
order_by()
reverse()
distinct()
#2、特殊的QuerySet
values()       返回一个可迭代的字典序列
values_list() 返回一个可迭代的元祖序列
#3、返回具体对象的
get()
first()
last()
#4、返回布尔值的方法有:
exists()
#5、返回数字的方法有
count()

猜你喜欢

转载自www.cnblogs.com/liangzhenghong/p/11278774.html
今日推荐