python中ORM对应关系查询

models.py 在models中模型建立 对应建立表关系(单表)

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()  # 年月日
    '''
    datefield
    datetimefield
    两个重要参数
    auto_now:每次操作数据的时候,该字段会自动将当前时间更新
    auto_now_add:创建数据的时候会自动将当前创建时间记录下来
    之后只要不人为修改就一直不变
    '''

    def __str__(self):
        return self.name

test.py单表查询

import os #测试环境配置
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoday64.settings")
    import django
    django.setup()
    from app01 import models

    增(create)
    方法一(对应user表对象.create方法)
    res=models.User.objects.create(name='jason',age=18,register_time='2002-1-21')
    print(res)
    方法二(产生对象后.save方法)
    import datetime
    ctime =datetime.datetime.now()
    user_obj =models.User(name ='egon',age=84,register_time=ctime)
    user_obj.save()

    删(先filter,后.delete方法)
    res = models.User.objects.filter(pk=2).delete()
    print(res)
    '''
    pk会自动查到到当前表的主键字段 指代的就是当前表的主键字段
    用了pk之后 你就不需要知道当钱的主键字段叫什么了
    因为是自动查找的
    '''
    (先产生对象,后对象.delete)
    user_obj= models.User.objects.filter(pk=1).first()
    user_obj.delete()

    修改(先filter,后update方法)
    models.User.objects.filter(pk=4).update(name='egonDSB')

    user_obj = models.User.objects.get(pk=4)
    get方法返回的直接就是当前数据对象
    但是该方法不推荐使用,一旦数据不存在,方法会报错
    而filter则不会,所以我们还是用filter
    user_obj.name = 'egonPPP'
    user_obj.save()

    必会必知131.all() 查询所有数据 queryset对象中字典套对象
    2.filter() 带有过滤条件的查询
    3.get() 直接拿数据对象 如果不存在直接报错
    4.first() 拿queryset里面第一个元素
    res = models.User.objects.all()
    print(res)
    5.last()
    6.values() 可以指定获取数据的字段 列表套字典
    res=models.User.objects.values('name','age')
    print(res)
    7.values_list()列表套元组 功能更强大  <QuerySet [('jason',), ('egonPPP',)]>
    res = models.User.objects.values_list('name')
    print(res.query) 查看内部分装的sql语句
    '''
    #查看内部封装的sql语句 有个配置文件复制过来可以查看SQL语句的执行
    上述查看sql语句的方式,只能用于queryset对象
    只有queryset对象才能够点击query查看内部的sql语句
    '''
    8.distinct()去重
    res= models.User.objects.all().values('name','age').distinct()
    print(res)
    '''
    一定要是一模一样的数据 
    如果带有主键那么肯定不一样 往后的查询中一定不要忽略主键
    '''
    9.order_by()
    res = models.User.objects.order_by('age')  # 默认升序
    res = models.User.objects.order_by('-age') 降序
    print(res)
    10.reverse() 反转的前提是 数据已经排过序了
    res= models.User.objects.all()
    res1=models.User.objects.order_by('age').reverse()
    print(res)
    print(res1)
    11.count() 统计当前数据个数
    res =models.User.objects.count()
    print(res)
    12.exclude() 排除在外
    res = models.User.objects.exclude()
    13.exists() 基本用不到 因为数据本身就自带布尔值 根本用不到 返回布尔值
    res = models.User.objects.filter(pk=10).exists()
    print(res)

    神奇的双下划线查询
    1 年龄大于35岁的数据(__gt大于)
    res= models.User.objects.filter(age__gt=35)
    print(res)
    2.年龄小于35岁的数据(__lt小于)
    res= models.User.objects.filter(age__lt=35)
    print(res)
    大于等于(__gte)
    res=models.User.objects.filter(age__gte=32)
    print(res)
    小于等于(__lte)
    res=models.User.objects.filter(age__lte=32)
    print(res)

    年龄是18或者32或者是40(__in在列表中的单个)
    res =models.User.objects.filter(age__in=[18,32,40])
    print(res)
    年龄在1840岁之都要(__range在列表中的所有)
    res=models.User.objects.filter(age__range=[18,40])
    print(res)

    查询出名字里含有n的数据 模糊查询(__contains)
    res =models.User.objects.filter(name__contains='s')
    print(res)
    是否区分大小写 查询出名字里面含有p的数据  默认是区分大小写的
    res =models.User.objects.filter(name__contains='s')
    print(res)
    忽略大小写 不区分大小写(__icontains)
    res = models.User.objects.filter(name__icontains='p')
    print(res)
    __startswith  __endswith 开始结束
    res =models.User.objects.filter(name__startswith='j')
    res1 =models.User.objects.filter(name__endswith='j')
    print(res,res1)
    查询出注册时间是2020-01 月份 年份 __month  __year
    res=models.User.objects.filter(register_time__month='1')
    res=models.User.objects.filter(register_time__year='2020')
    print(res)

models.py 在models中模型建立 对应建立表关系(多表)

from django.db import models
Create your models here.

class Book(models.Model):图书表建立:book表
	title = models.CharField(max_length=32)名称:字段charField,最大长度:32位
	price = models.DecimalField(max_digits=8, decimal_places=2)价格:小数字段DecimalField,最大8位,小数位数2位
	publish_data = models.DateField(auto_now_add=True)出版时间:DateField  auto_now_add=True:以当前图书表注册时间记录

	publish = models.ForeignKey(to='Publish') 
	ForeignKey:图书和出版社关系 :一对多,一个出版社对多个图书,一本书一个出版社,字段建在多的那一方
	authors = models.ManyToManyField(to='Author') 
	ManyToManyField:图书和作者关系 :多对多,多个作者对多个图书,字段建在查询频率多的那一方
	
class Publish(models.Model):出版社表建立:Publish表
	name = models.CharField(max_length=32) 出版社名字_字段:name CharField字段类型,最大长度32位
	addr = models.CharField(max_length=64) 出版社地址_字段:addr CharField字段类型,最大长度64位
	email = models.EmailField()  本质还是varchar(254)出版社邮箱_字段
	该字段类型不是给models看的 而是给我们后面会学到的校验性组件看的
	
class Author(models.Model):作者表建立:Author表
	name = models.CharField(max_length=32)  作者名字 字段:name CharField  字段类型,最大长度32位
	age = models.IntegerField()   作者年龄 字段:age IntegerField 字段类型

	auther_detail = models.OneToOneField(to='AuthorDetail') OneToOneField:作者表和作者明细表关系 一对一

class AuthorDetail(models.Model):作者明细表建立:AuthorDetail表
	phone = models.BigIntegerField()                  电话号码 字段:电话号码用Bigint或者用charfield
	addr = models.CharField(max_length=64)            作者地址:地址 CharField 最大长度64位

   
	一对多外键增删改查
    增 (create方法)
    1.直接写实际字段 id (book书增加出版社)
    models.Book.objects.create(title='三国演义', price=123.23, publish_id=1)
    2 虚拟字段 对象 
    publish_obj = models.Publish.objects.filter(pk=2).first()
    models.Book.objects.create(title='红楼梦', price=666.23, publish=publish_obj)

    删(delete方法)
    models.Publish.objects.filter(pk=1).delete() #级联删除
    
    修改(update方法)
    方法一:
    models.Book.objects.filter(pk=1).update(publish_id=2)
    方法二:
    publish_obj = models.Publish.objects.filter(pk=1).first()
    models.Book.objects.filter(pk=1).update(publish=publish_obj)

    多对多 增删改查 就是在操作第三张关系表
    models.Book.objects.create(title='论语', price=899.23, publish_id=1)
    models.Book.objects.create(title='聊斋', price=444.23, publish_id=2)
    models.Book.objects.create(title='老子', price=333.66, publish_id=1)

    如何给书籍添加作者?
    book_obj = models.Book.objects.filter(pk=1).first()
    print(book_obj.authors)  就类似于你已经到了第三张关系表了
    book_obj.authors.add(1)  书籍id1的书籍绑定一个主键为1的作者

    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    author_obj2 = models.Author.objects.filter(pk=3).first()
    book_obj.authors.add(author_obj,author_obj2)
    '''
    add给第三张关系表添加数据
        括号内既可以传数字也可以传对象 并且都支持多个
    '''
    删(remove)
    book_obj.authors.remove(1)
    括号内既可以传对象 又可以传数字 并且支持多个
    
    修改(set)
    book_obj.authors.set([1,2])
    括号内既可以传对象 又可以传数字 并且支持多个 括号内必须传一个可迭代对象
    先删除 后新增

    在第三张关系表中清空某个书籍与作者的绑定关系
    清除所有关系
    book_obj.authors.clear()
    '''
    clear
        括号内不要加任何参数
    '''

    基于对象的跨表查询
    '''
    正向查询按字段
    反向查询按表名小写_set.all()
    '''
    1.查询书籍主键为1的出版社
    book_obj = models.Book.objects.filter(pk=1).first()
     书查出版社 正向
    res = book_obj.publish
    print(res)
    print(res.name)
    print(res.addr)

    2.查询书籍主键为1的作者(一对多)
    book_obj = models.Book.objects.filter(pk=1).first()
    书查作者 正向
    res= book_obj.authors #app01.Author.None
    res= book_obj.authors.all() #<QuerySet [<Author: Author object>, <Author: Author object>]>
    print(res)

    3.查询作者jason的电话号码
    author_obj = models.Author.objects.filter(name='jason').first()
    res =author_obj.auther_detail
    print(res)
    '''
    在书写orm语句的时候跟写sql语句是一样的
    不要企图一次性将ORM语句写完 如果比较复杂 就写一点 看一点
    正向什么时候需要加.all()
        当你的结果可能有多个的时候就需要加.all()
        如果是一个则直接拿到数据对象
    '''
    4.查询出版社是东方出版的书(多对多)
    publish_obj =models.Publish.objects.filter(name='东方出版社').first()
    res =publish_obj.book_set.all()  反向查询按表名小写_set.all()
    print(res)

    5.查询作者是jason写过的书
    author_obj = models.Author.objects.filter(name='jason').first()
    res = author_obj.book_set.all()  反向查询按表名小写_set.all()
    print(res)

    6.查询手机号是110的作者姓名
    author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
    res = author_detail_obj.author
    print(res)
    print(res.name)
    print(res.addr)
    '''
    基于对象
        反向查询的时候:
            当你的查询结果可以有多个的时候 就必须加_set.all()
            当你的结果只有一个的时候 不需要加_set.all()
            自己总结出自己方便记忆的即可 每个人可以不同
    '''

    基于双下划线的跨表查询

    1.查询jason的手机号(一行代码搞定)
    res = models.Author.objects.filter(name='jason').values('auther_detail__phone')
    print(res)

    反向
    res = models.AuthorDetail.objects.filter(author__name ='jason') #拿作者姓名是jason的作者详情
    res = models.AuthorDetail.objects.filter(author__name='jason').values('phone', 'author__name')
    print(res)

    2.查询书籍主键为1的出版社和书的名称
    res = models.Book.objects.filter(pk=1).values('title','publish__name')
    print(res)
    反向
    res =  models.Publish.objects.filter(book__pk=1).values('name', 'book__title')
    print(res)
    3.查询书籍主键为1的作者姓名
    res= models.Book.objects.filter(pk=1).values('authors__name')
    print(res)
    反向
    models.Author.objects.filter(book__id=1).values('name')

    4. 查询书籍主键是1的作者的手机号
    res = models.Book.objects.filter(pk=1).values('authors__auther_detail__phone')
    print(res)
    '''
    只要掌握了正反向的概念
    以及双下划线
    你就可以无限制的跨表查询
    '''

猜你喜欢

转载自blog.csdn.net/yinlingjishu/article/details/109330665
今日推荐