django模型层 、 ORM查询

模型层 ORM查询

单表查询

前期准备工作需求:

如何只单独测试django中的某一个py文件
如何书写测试脚本

如何使用:

在任意一个py文件中书写以下代码
    应用下的tests
    或者自己新建一个
import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()

前期准备工作图片分析:

第一步:先到 settings.py配置信息:

第二步:modles 中设置数据信息

auto_now:每次修改数据的时候 都会自动将最新的更新时间记录下来auto_now_add:只在创建数据的时候将创建时间自动记录下来 之后不会自动改变

第三步: 从mange中获取四句信息,复制到相应的文件中(tests中 看你自己)在进行导入相关文件(不到入回报错)

必知必会16条

   """
    必知必会16条
        1.create()
        2.all()
        3.filter()
        4.update()
        5.delete()
        6.first()
        7.last()
        8.get()
        9.values()
        10.values_list()
        11.order_by()
        12.count()
        13.exclude()
        14.exists()
        15.reverse()
        16.distinct()
    """

1.create()

"""
1.create()  返回值就是当前被创建数据的对象本身
# 日期可以手动给
models.Movie.objects.create(title='盲僧',price=4800,publish_time='2016-1-1')

# 还可以直接传日期对象
from datetime import date
ctime = date.today()
models.Movie.objects.create(title='寒冰', price=500, publish_time=ctime)
"""

效果:

2.all() queryset对象

2.all()            queryset对象
res = models.Movie.objects.all()
print(res)

效果:

3.filter() queryset对象

res = models.Movie.objects.filter(id=1)
res = models.Movie.objects.filter(pk=1)  # pk指代的就是当前表的主键字段名  自动查找非常方便
 res = models.Movie.objects.filter(pk=1,title='python入门')  # 括号内可以放多个条件默认是AND关系

效果:

4.get()

# 4.get()      直接获取对象本身  不推荐使用  当查询条件不存在的时候直接报错
    res = models.Movie.objects.get(pk=1)
    print(res)
    print(res.title)
    print(res.price)
    res = models.Movie.objects.get(pk=1000)
    res = models.Movie.objects.filter(pk=1000)
    print(res)

效果:

    res = models.Movie.objects.get(pk=1)
    print(res)
    print(res.title)
    print(res.price)

res = models.Movie.objects.get(pk=1000)#当查询条件不存在的时候直接报错
res = models.Movie.objects.filter(pk=1000)#为空
print(res)

效果:

5.values() QuerySet对象 [{},{},{}] 获取指定字段对的数据

 # 5.values()   QuerySet对象  [{},{},{}]     获取指定字段对的数据
    res = models.Movie.objects.values('title','publish_time')
    print(res)
    print(res.query)

效果:

6.values_list()

6.values_list()  QuerySet对象  [(),(),()]  获取指定字段对的数据
res = models.Movie.objects.values_list('title','price')
print(res)

效果:

7.first()

    # 7.first()    数据对象        取第一个元素对象
    res = models.Movie.objects.filter().first()
    print(res)

效果:

8.last() 数据对象

8.last()    数据对象          取最后一个元素对象
res = models.Movie.objects.last()
print(res)

效果:

9.update() 更新数据

# 9.update()  更新数据      返回值是受影响的行数
res = models.Movie.objects.filter(pk=2).update(title='皇子')
res = models.Movie.objects.filter(pk=1).update(title='金瓶美2',price=666)
print(res)

效果:

res = models.Movie.objects.filter(pk=2).update(title='皇子')
print(res)

res = models.Movie.objects.filter(pk=1).update(title='蛮子',price=4300)
print(res)

10.delete() 删除数据

# 10.delete()  删除数据    返回值(1, {'app01.Movie': 1})  受影响的表及行数
res = models.Movie.objects.filter(pk=3).delete()
print(res)

效果:

11.count() 统计数据条数

11.count()  统计数据条数
res = models.Movie.objects.count()
print(res)

效果:

12.order_by 按照指定字段排序

12.order_by  按照指定字段排序
res = models.Movie.objects.order_by('price')  # 默认是升序
res = models.Movie.objects.order_by('-price')  # 减号就是降序
print(res)

效果:

升序:

res = models.Movie.objects.order_by('price')  # 默认是升序
print(res)


降序:由高到底

res = models.Movie.objects.order_by('-price')  # 减号就是降序
print(res)

13.exclude() 排除什么什么之外 少选条件

13.exclude()  排除什么什么之外  少选条件
res = models.Movie.objects.exclude(pk=1)
print(res)

效果:

14.exists() 返回的是布尔值 判断前面的对象是否有数据 了解即可

14.exists()   返回的是布尔值  判断前面的对象是否有数据  了解即可
res = models.Movie.objects.filter(pk=1000).exists()
print(res)

效果:


15.reverse() 反转

15.reverse()  反转
res = models.Movie.objects.order_by('price').reverse()
print(res)

效果:

16.distinct() 去重:

16.distinct()  去重:去重的前提 必须是由完全一样的数据的才可以
res =models.Movie.objects.values('title','price').distinct()
print(res)

效果:


神奇的双下划线查询

1.查询价格大于200的电影

 # 1.查询价格大于200的电影
 res = models.Movie.objects.filter(price__gt=200)
 print(res)

效果:下表都大于200


2.查询价格小于1000的电影

# 2.查询价格小于1000的电影
res = models.Movie.objects.filter(price__lt=1000)
print(res)

效果:

3.查询价格大于等于876.23的电影

# 3.查询价格大于等于4500的电影
res = models.Movie.objects.filter(price__gte=4500)
print(res.query)

效果:

4.查询价格小于等于876.23的电影

res = models.Movie.objects.filter(price__lte=500)
print(res)

效果:

5.查询价格是500 或5000 或4300

# 5.查询价格是500 或5000 或4300
res = models.Movie.objects.filter(price__in=[500,5000,4300])
print(res)

效果:

6.查询价格在4000到6000之间的电影 顾头也顾尾

# 6.查询价格在4000到6000之间的电影  顾头也顾尾
res = models.Movie.objects.filter(price__range=(4000,6000))
print(res)

效果:

7.查询电影名中包含字母p的电影

    """
    模糊查询:
        关键字 like
        关键符号
            %
            _
    """

# 7.查询电影名中包含字母p的电影
res = models.Movie.objects.filter(title__contains='p')  # 默认是区分大小写
res = models.Movie.objects.filter(title__icontains='p')  # i忽略大小写
print(res)

效果:

默认是区分大小写


忽略大小写

8.查询2016年出版的电影

# 8.查询2016年出版的电影
res = models.Movie.objects.filter(publish_time__year=2016)
print(res)

效果:

9.查询是1月份出版的电影

  res = models.Movie.objects.filter(publish_time__month=1)
  print(res)

效果:

多表查询

1.图书管理系统表创建

一对多和一对一字段 外键字段会自动在后面加_id后缀
from django.db import models

# Create your models here.

class Movie(models.Model):
    title = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_time = models.DateField()
    # publish_time = models.DateTimeField()  #年月日 时分秒

    def __str__(self):
        return self.title

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)  # 该字段新增数据自动添加 无需考虑

    # 出版社   一对多    外键字段建在多的一方
    publish = models.ForeignKey(to='Publish')
    # 作者     多对多    外键字段建在任意一方均可 推荐你建在查询频率较高的表
    authors = models.ManyToManyField(to='Author')

    # 库存数
    kucun = models.BigIntegerField(default=1000)
    # 卖出数
    maichu = models.BigIntegerField(default=1000)

    def __str__(self):
        return self.title

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 作者详情   一对一    外键字段建在任意一方均可 推荐你建在查询频率较高的表
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=32)

2.外键字段的增删改查

一对多 publish

1.增  直接写实际的表字段 publish_id
models.Book.objects.create(title='三国演义',price=123.23,publish_id=2)

# 2.增
publish_obj = models.Publish.objects.get(pk=1)
models.Book.objects.create(title='金瓶美',price=66.66,publish=publish_obj)

效果:

查:

# 改1
models.Book.objects.filter(pk=1).update(publish_id=3)
2.
publish_obj = models.Publish.objects.get(pk=4)
models.Book.objects.filter(pk=1).update(publish=publish_obj)

效果:


# 删
"""
 外键字段在1.X版本中默认就是级联更新级联删除的
 2.X版本中 则需要你自己手动指定
      百度一大堆
 """

多对多

1 给书籍绑定作者关系 add

"""
add专门给第三张关系表添加数据
括号内即可以传数字也可以传对象  并且都支持传多个
"""

代码:

# 多对多
# 1 给书籍绑定作者关系   add
# book_obj = models.Book.objects.filter(pk=1).first()
# 书籍和作者的关系是由第三张表绝对 也就意味着你需要操作第三张表
# print(book_obj.authors)  # 书籍对象点虚拟字段authors就类似于已经跨到书籍和作者的第三张关系表中
# book_obj.authors.add(1)  # 给书籍绑定一个主键为1的作者
# book_obj.authors.add(2,3)
2.
# author_obj = models.Author.objects.get(pk=1)
# author_obj1 = models.Author.objects.get(pk=3)
# book_obj.authors.add(author_obj)
# book_obj.authors.add(author_obj,author_obj1)

"""
    add专门给第三张关系表添加数据
        括号内即可以传数字也可以传对象  并且都支持传多个
    """

效果:

# book_obj = models.Book.objects.filter(pk=1).first()
# 书籍和作者的关系是由第三张表绝对 也就意味着你需要操作第三张表
# print(book_obj.authors)  # 书籍对象点虚拟字段authors就类似于已经跨到书籍和作者的第三张关系表中

2 移除书籍与作者的绑定关系 remove

"""
    remove专门给第三张关系表移除数据
        括号内即可以传数字也可以传对象  并且都支持传多个
    """
# 2 移除书籍与作者的绑定关系  remove
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.remove(2)
# book_obj.authors.remove(1,3)
# author_obj = models.Author.objects.get(pk=2)
# author_obj1 = models.Author.objects.get(pk=3)
# book_obj.authors.remove(author_obj)
# book_obj.authors.remove(author_obj,author_obj1)
"""
    remove专门给第三张关系表移除数据
        括号内即可以传数字也可以传对象  并且都支持传多个
    """

效果:

# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.remove(2)

# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.remove(1,3)

author_obj = models.Author.objects.get(pk=2)
author_obj1 = models.Author.objects.get(pk=3)
book_obj.authors.remove(author_obj)
book_obj.authors.remove(author_obj,author_obj1)


3 修改书籍与作者的关系 set

    """
    set 修改书籍与作者的关系
        括号内支持传数字和对象 但是需要是可迭代对象
    """
# 3 修改书籍与作者的关系   set
1.
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.set((3,))
book_obj.authors.set((2,3))
2.
author_obj = models.Author.objects.get(pk=2)
author_obj1 = models.Author.objects.get(pk=3)
book_obj.authors.set((author_obj,))
book_obj.authors.set([author_obj,author_obj1])
    """
    set 修改书籍与作者的关系
        括号内支持传数字和对象 但是需要是可迭代对象
    """

效果:


4 清空书籍与作者关系

    """
    clear()  清空关系
    不需要任何的参数
    """
# 4 清空书籍与作者关系
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.clear()  # 去第三张表中清空书籍为1的所有数据
    """
    clear()  清空关系
    不需要任何的参数
    """

效果:

3.跨表查询

跨表查询的方式

1.子查询

1.子查询  将一张表的查询结果当做另外一张表的查询条件
正常解决问题的思路 分步操作

2.链表查询

2.链表查询
inner join
left join
right join
union

建议

建议:在写sql语句或者orm语句的时候 千万不要想着一次性将语句写完 一定要写一点查一点再写一点

正反向的概念

正向

跨表查询的时候 外键字段是否在当前数据对象中 如果在
查询另外一张关系表  叫正向

反向

如果不在叫反向

口诀

口诀:
正向查询按外键字段
反向查询按表名小写
_set

1.基于对象的跨表查询(子查询)

   """
    正向查询的时候 当外键字段对应的数据可以有多个的时候需要加.all()
    否则点外键字典即可获取到对应的数据对象
    """

1.查询书籍pk为1的出版社名称

# 基于对象的跨表查询(子查询)
1.查询书籍pk为1的出版社名称
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish)
print(book_obj.publish.name)
print(book_obj.publish.addr)

效果:

2.查询书籍pk为1的所有作者的姓名

# 2.查询书籍pk为1的所有作者的姓名
book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.authors)  # app01.Author.None
print(book_obj.authors.all())
author_list = book_obj.authors.all()
for author_obj in author_list:
    print(author_obj.name)

效果:

3.查询作者pk为1的电话号码

# 3.查询作者pk为1的电话号码
author_obj = models.Author.objects.filter(pk=1).first()
print(author_obj.author_detail)
print(author_obj.author_detail.phone)
print(author_obj.author_detail.addr)

效果:

   """
    正向查询的时候 当外键字段对应的数据可以有多个的时候需要加.all()
    否则点外键字典即可获取到对应的数据对象
    """

4.查询出版社名称为东方出版社出版过的书籍

# 4.查询出版社名称为东方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set)  # app01.Book.None
print(publish_obj.book_set.all())

效果:

5.查询作者为jason写过的书

# 5.查询作者为孙尚香写过的书
author_obj = models.Author.objects.filter(name='孙尚香').first()
print(author_obj.book_set)  # app01.Book.None
print(author_obj.book_set.all())

效果:

6.查询手机号为180的作者姓名

# 6.查询手机号为180的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=180).first()
print(author_detail_obj.author)
print(author_detail_obj.author.name)
print(author_detail_obj.author.age)

效果:

2.基于双下划线的跨表查询

"""
    基于对象的反向查询 表名小写是否需要加_set.all()
        一对多和多对多的时候需要加
        一对一不需要
    """

1.查询书籍pk为1的出版社名称

正向
# 正向
res = models.Book.objects.filter(pk=1).values('publish__name')  # 写外键字段 就意味着你已经在外键字段管理的那张表中
print(res)

效果:

反向
# res = models.Publish.objects.filter(book__pk=1)  # 拿出版过pk为1的书籍对应的出版社
res = models.Publish.objects.filter(book__pk=1).values('name')
    print(res)

效果:

2.查询书籍pk为1的作者姓名和年龄

正向
# 正向
# res = models.Book.objects.filter(pk=1).values('title','authors__name','authors__age')
# print(res)

效果:

反向
res = models.Author.objects.filter(book__pk=1)  # 拿出出版过书籍pk为1的作者
res1 = models.Author.objects.filter(book__pk=1).values('name','age','book__title')
print(res)
print(res1)

效果:

3.查询作者是jason的年龄和手机号

正向
# 正向
res=models.Author.objects.filter(name='jason').values('age','author_detail__phone')
# print(res)

效果:

反向
res = models.AuthorDetail.objects.filter(author__name='孙尚香')  # 拿到jason的个人详情
res1 = models.AuthorDetail.objects.filter(author__name='孙尚香').values('phone','author__age')
print(res)
print(res1)

效果:

查询书籍pk为的1的作者的手机号

"""
    只要表之间有关系  你就可以通过正向的外键字段或者反向的表名小写 连续跨表操作
    """
# 查询书籍pk为的1的作者的手机号
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)

res = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')
print(res)

效果:

聚合查询

导入:

from django.db.models import Max,Min,Avg,Count,Sum

关键字:

aggregate

查询所有书的平均价格

# 查询所有书的平均价格
from django.db.models import Max, Min, Avg, Count, Sum
res = models.Book.objects.aggregate(avg_num=Avg('price'))
print(res)

效果:

查询价格最贵的书

from django.db.models import Max, Min, Avg, Count, Sum
# 查询价格最贵的书
res = models.Book.objects.aggregate(max_num=Max('price'))
print(res)

效果:

全部使用一遍

# 全部使用一遍
# res = models.Book.objects.aggregate(Avg("price"), Max("price"), Min("price"),Count("pk"),Sum('price'))
# print(res)

效果:

分组查询

关键字:

annotate
from django.db.models import Max, Min, Avg, Count, Sum
# 1.统计每一本书的作者个数
res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
print(res)

1.统计每一本书的作者个数

2.统计出每个出版社卖的最便宜的书的价格

res=models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price','book__title')
print(res)

3.统计不止一个作者的图书

res=models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title')
print(res)

4.查询各个作者出的书的总价格

res=models.Author.objects.annotate(price_sum=Sum('book__price')).values('name','price_sum')
print(res)

效果:

5.如何按照表中的某一个指定字段分组

 res = models.Book.objects.values('price').annotate()  就是以价格分组

F与Q查询

导入:

from django.db.models import F,Q

1.查询库存数大于卖出数的书籍

from django.db.models import F,Q
# 1.查询库存数大于卖出数的书籍
# res = models.Book.objects.filter(kucun__gt=F('maichu'))
# print(res)

效果:

2.将所有书的价格提高100

 res = models.Book.objects.update(price=F('price') + 100)

效果:

"""帮你获取到表中某个字段对应的值"""

Q能够改变查询的条件关系 and or not

1.查询书的名字是python入门或者价格是1000的书籍

# 1.查询书的名字是python入门或者价格是1000的书籍
res = models.Book.objects.filter(title='python入门',price=1000)  # and关系
res1 = models.Book.objects.filter(Q(title='python入门'),Q(price=1000))  # 逗号是and关系
res2 = models.Book.objects.filter(Q(title='python入门')|Q(price=1000))  # |是or关系
res3 = models.Book.objects.filter(~Q(title='python入门')|Q(price=1000))  # ~是not关系
print(res.query)
print(res1.query)
print(res2.query)
print(res3.query)

效果:

Q的高阶用法

q = Q()
q.connector = 'or'  # q对象默认也是and关系  可以通过connector改变or
q.children.append(('title','python入门'))
q.children.append(('price',1000))

res = models.Book.objects.filter(q)
print(res)

效果:

原文地址:https://www.cnblogs.com/WQ577098649/p/12169287.html

时间: 2024-10-07 09:23:05

django模型层 、 ORM查询的相关文章

一 Django模型层简介

模型 django提供了一个强大的orm(关系映射模型)系统. 模型包含了你要在数据库中创建的字段信息及对数据表的一些操作 使用模型 定义好模型后,要告诉django使用这些模型,你要做的就是在配置文件中的INSTALLED_APPS中添加模型所在的应用名称 字段类型 模型中的每个字段都是Field类相应的实例,django根据Field类型来确定以下信息: 列类型,告知数据库要存储那种数据 渲染表单时使用的默认HTML widget 验证,被用在admin和表单中 通用字段参数(常用) nul

Django模型层之单表操作

Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql.oracle.Microsoft SQL Server等. 如果应用程序需要操作数据(比如将用户注册信息永久存放起来),那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作mysql数据库,详见图一^①^ 但是直接编写原生sql语句会存在两方面的问题,严

Django模型层之更多操作

Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型,范围在-2147483648 to 2147483647. CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,日期格式 YYYY-MM-DD,相当于Python中的d

03 Django模型层: 常用(非常用)字段和参数

Django模型层: 常用(非常用)字段和参数 1 ORM字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型,范围在 -2147483648 to 2147483647. CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,日期格式? YYYY-MM-DD,相当于Python中的

Django之模型层&ORM操作

一. 单表查询:  1.在模型层创建模型表: from django.db import models # Create your models here. # 单表查询表 class User(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() register_time = models.DateField()      2.连接MySQL,创建表 (具体操作见https://ww

9.17 模型层 ORM 单表操作

1 创建模型 创建名为book的app,在book下的models.py中创建模型: from django.db import models # Create your models here. class Book(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32) state=models.BooleanField() pub_date=models.DateF

Django模型层(1)

ORM简介: MVC或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动 ORM是"对象-关系-映射"的简称. 单表操作 创建模型: 创建名为book的app,在book下的model.py中创建模型 from django.db import models # Create your models here.

Django基础五之django模型层(一)单表操作

目录 一 ORM简介 二 单表操作 一.创建表 创建模型 2 更多字段和参数 3 settings配置 4.自定义字段(了解) 二.添加表纪录 方式1 方式2(用的多) 方式3:批量插入 三.查询表纪录 查询API(都是重点) 基于双下划线的模糊查询 四.删除表纪录 五.修改表纪录 三 章节作业 1 图书管理系统 2 查询操作练习 四 xxx 本节目录 一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,

Django基础五之django模型层(二)多表操作

目录 一 创建模型 关于db_column和verbose_name 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询(基于join实现的) 进阶练习(连续跨表) 五 聚合查询.分组查询.F查询和Q查询 查询练习 F查询与Q查询 F查询 Q查询 六 ORM执行原生sql语句(了解) 执行原生查询 直接执行自定义SQL 七 Python脚本中调用Django环境(django外部脚本使用models) 八 补充多个app配置models 本节目录 一 创建模型 表和表之间的关系