模型层
Posted lakei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模型层相关的知识,希望对你有一定的参考价值。
django ORM操作
关键性字段及参数
DateField 年月日
DateTimeField 年月日时分秒
auto_now :每次操作该数据都会自动跟新时间
auto_now_add:新增数据的时候会将当前
import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day58.settings") import django django.setup() from app01 import 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() def __str__(self): return ‘对象的名字:%s‘%self.name #多表查询 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) #外键关系 publish = models.ForeignKey(to=‘Publish‘) authors = models.ManyToManyField(to=‘Author‘) def __str__(self): return ‘书籍对象的名字:%s‘%self.title class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) email = models.EmailField() #对应的就是varchar类型 def __str__(self): return ‘出版社对象的名字:%s‘%self.name class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() authordetail = models.OneToOneField(to=‘AuthorDetail‘) def __str__(self): return ‘作者对象的名字:%s‘%self.name class AuthorDetail(models.Model): phone = models.CharField(max_length=32) addr = models.CharField(max_length=32)
单表操作
#新增数据 #基于create创建 user_obj = models.User.objects.create(name=‘tank‘,age=74,reister_time=‘2019-2-4‘) print(user_obj.register_time) #2019-2-4
有返回值 返回的就是数据对象本身
from datetime import datetime ctime = datetime.now() models.User.create(name=‘egon‘,age=18,regist_time=ctime) #基于对象的绑定方法创建 user_obj =models.User(name=‘kevin‘,age=30,register_time=‘2019-1-1‘) user_obj.save() #修改数据 #基于对象 user_obj = models.User.objectes.filter(name=‘jason‘).first() user_obj.age = 17 user_obj.save() #基于Queryset models.User.objects.filter(name=‘kevi‘).update(age=66) #删除数据 #基于Queryset models.User.objects.filter(name=‘egon‘).delete() #基于数据对象 user_obj = models.User.objects.filter(name=‘owen‘).first() user_obj.delete() #数据对象也可以delete()删除
查询方法
#查询数据 #1 all() 查询所有结果 #2 filter(**kwargs) 它包含了与所给筛选条件相匹配的对象 res = models.User.objects.filter(name=‘jason‘,age=17) #filter内可以放多个限制条件 注意!!条件之间是and关系 print(res) #<QuerySet [<User: 对象的名字:jason>]> # 3 get(**kwargs) 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误 #不推荐使用 #4 exclude(**kwargs) 它包含了与所给筛选条件不匹配的对象 排除 res = models.User.objects.exclude(name=‘jason‘) print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>]> #5 order_by(*field) 对查询结果排序(‘-id‘)/(‘price‘) 数字和字符串都可以 默认升序 前面加 - 就是降序 # res = models.User.objects.order_by(‘age‘) #默认是升序 # print(res) #<QuerySet [<User: 对象的名字:jason>, <User: 对象的名字:kevin>, <User: 对象的名字:tank>]> # res = models.User.objects.order_by(‘-age‘) # print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>, <User: 对象的名字:jason>]> # res = models.User.objects.order_by(‘name‘) # print(res) #<QuerySet [<User: 对象的名字:jason>, <User: 对象的名字:kevin>, <User: 对象的名字:tank>]> # res = models.User.objects.order_by(‘-name‘) # print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>, <User: 对象的名字:jason>]> #6 reverse() 对查询结果反向排序 》》》前面要先排序才能反向 # res = models.User.objects.order_by(‘age‘).reverse() # print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>, <User: 对象的名字:jason>]> #7 count() 返回数字库中匹配查询(Queryset)的对象数量 # res = models.User.objects.count() # print(res,type(res)) #3 # res = models.User.objects.all().count() # print(res,type(res)) #3 #8 first() 返回第一条记录 res = models.User.objects.all().first() res= models.User.objects.all()[0] print(res) #对象的名字:tank #9 last() 返回最后一条记录 res = models.User.objects.all().last() print(res) #对象的名字:jason #10 exitsts() 如果Queryset包含数据 就返回True 否则返回False res = models.User.objects.all().exists() res1 = models.User.objects.filter(name=‘jason‘,age=3).exists() print(res,res1) #True False #11 values(*field) 返回一个valuesQuerst 一个特殊的queryset 运行后得到的并不是一系列models的实例化对象,而是一个可迭代的字典序列 res = models.User.objects.values(‘name‘) #列表套字典 print(res) #<QuerySet [‘name‘: ‘tank‘, ‘name‘: ‘kevin‘, ‘name‘: ‘jason‘]> res = models.User.objects.values(‘name‘,‘age‘) #列表套字典 print(res) #<QuerySet [‘name‘: ‘tank‘, ‘age‘: 73, ‘name‘: ‘kevin‘, ‘age‘: 66, ‘name‘: ‘jason‘, ‘age‘: 17]> #12 values_list(*field) 它与values() 非常相似 它返回的是一个元组序列 values返回的是一个字典序列 res = models.User.objects.values_list(‘name‘,‘age‘) #列表套元组 print(res) #<QuerySet [(‘tank‘, 73), (‘kevin‘, 66), (‘jason‘, 17)]> #13 distinct() 从返会结果中剔除重复记录 去重的对象必须是完全相同的数据才能取重 res = models.User.objects.values(‘name‘,‘age‘).distinct() print(res) #<QuerySet [‘name‘: ‘tank‘, ‘age‘: 73, ‘name‘: ‘kevin‘, ‘age‘: 66, ‘name‘: ‘jason‘, ‘age‘: 17]>
单表操作 基于双下划线的查询
#神奇的双下划线查询 #查询年纪大于44岁的用户 res = models.User.objects.filter(age__gt=44) print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>]> #查询年纪小于44岁的用户 res= models.User.objects.filter(age__lt=44) print(res) #<QuerySet [<User: 对象的名字:jason>, <User: 对象的名字:jason>]> # 查询年纪大于等于44岁的用户 res= models.User.objects.filter(age__gte=44) print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>, <User: 对象的名字:laj>]> # 查询年轻小于等于44岁的用户 res = models.User.objects.filter(age__lte=44) print(res) #<QuerySet [<User: 对象的名字:jason>, <User: 对象的名字:jason>, <User: 对象的名字:laj>]> # 查询年龄是44或者22或者73的用户 res = models.User.objects.filter(age__in=[44,22,73]) print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:laj>]> # 查询年龄在22到44范围内 res = models.User.objects.filter(age__range=[22,44]) print(res) #<QuerySet [<User: 对象的名字:laj>]> 包含了44 # 查询名字中包含字母n的用户 sqlite数据库演示不出来大小写的情况!!! res = models.User.objects.filter(name__contains=‘n‘) #区分大小写 print(res) #<QuerySet [<User: 对象的名字:tank>, <User: 对象的名字:kevin>, <User: 对象的名字:jason>, <User: 对象的名字:jason>]> res = models.User.objects.filter(name__icontains=‘n‘) #无视大小写 print(res) # 查询名字以j开头的用户 res = models.User.objects.filter(name__startswith=‘j‘) print(res) #<QuerySet [<User: 对象的名字:jason>, <User: 对象的名字:jason>]> # 查询名字以n结尾的用户 res = models.User.objects.filter(name__endswith=‘n‘) print(res) #<QuerySet [<User: 对象的名字:kevin>, <User: 对象的名字:jason>, <User: 对象的名字:jason>]> # 查询注册是在2017年的用户 res = models.User.objects.filter(register_time__year=2017) print(res) #<QuerySet [<User: 对象的名字:jason>, <User: 对象的名字:jason>]>
多表操作 增删改
#多表操作 #新增 models.Book.objects.create(title=‘红楼梦‘,price=66.66,publish_id=1) #传数据对象 publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title=‘三国演义‘,price=‘199‘,publish=publish_obj) #修改 #Queryset修改 models.Book.objects.filter(pk=6).update(publish_id=3) publish_obj = models.Publish.objects.filter(pk=4).first() models.Book.objects.filter(pk=6).update(publish=publish_obj) #对象修改 book_obj = models.Book.objects.filter(pk=6).first() book_obj.publish_id = 1 #点表中真是存在的字段名 点表中的publish_id的话就写数字 book_obj.save() book_obj = models.Book.objects.filter(pk=6).first() publish_obj = models.Publish.objects.filter(pk=3).first() book_obj.publish = publish_obj #点orm中字段名 传该字段对应的表的数据对象 点orm里面的字段名的话 就传对象 publish_obj.save() #删除 models.Book.objects.filter(pk=6).delete() models.Publish.objects.filter(pk=4).delete() book_obj = models.Book.objects.filter(pk=5).first() book_obj.delete() #数据对象直接删除
多对多操作第三张表
#给书籍绑定与作者之间的关系 #添加关系 add 支持传数字或 对象, 并且都可以传多个 book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.add(4) book_obj.authors.add(2,3,4,5) author_obj = models.Author.objects.filter(pk=4).first() author_obj1 = models.Author.objects.filter(pk=3).first() book_obj.authors.add(author_obj,author_obj1) #修改书籍与作者关系 set() set传的必须是可迭代对象!!! #可以传数字或对象 并且支持传多个 book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.set((4,)) #这个可以用来删除书籍的作者直接重置关系 book_obj.authors.set((4,2)) author_list = models.Author.objects.all() book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.set(author_list) #queryset对象 #删除书籍与作者的绑定关系 book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.remove(2) book_obj.authors.remove(3,4) author_obj = models.Author.objects.all().first() book_obj.authors.remove(author_obj) author_list = models.Author.objects.all() book_obj.authors.remove(*author_list) #需要将queryset打散 #清空 clear() 清空的是你当前这个表记录对应的绑定关系 book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.clear()
基于对象的表操作 (正向查询按字段 反向查询按表名小写)
正向查询
# 查询书籍是三国演义的出版社邮箱 book_obj = models.Book.objects.filter(title=‘三国演义‘).first() print(book_obj.publish.email) #[email protected] # 查询书籍是三国演义的作者的姓名 book_obj = models.Book.objects.filter(title=‘三国演义‘).first() print(book_obj.authors.all()) # <QuerySet [<Author: 作者对象的名字:jason>, <Author: 作者对象的名字:kevin>]> # 查询作者为jason电话号码 user_obj = models.Author.objects.filter(name=‘jason‘).first() print(user_obj.authordetail.phone) #120
反向查询 (表名小写_set)
# 查询出版涩是东方出版涩出版的书籍
publish_obj = models.Publish.objects.filter(name=‘东方出版涩‘).first()
print(publish_obj.book_set) #app01.Book.None !!!! 出现就点all()
print(publish_obj.book_set.all()) #<QuerySet [<Book: 书籍对象的名字:小王子>, <Book: 书籍对象的名字:三国演义>]> # 查询作者jason写过的所有的书 author_obj = models.Author.objects.filter(name=‘jason‘).first() print(author_obj.book_set) #app01.Book.None print(author_obj.book_set.all()) #<QuerySet [<Book: 书籍对象的名字:围城>, <Book: 书籍对象的名字:小王子>, <Book: 书籍对象的名字:三国演义>]> # 查询作者电话号码是390的作者姓名 authordetail_obj = models.AuthorDetail.objects.filter(phone=390).first() print(authordetail_obj.author.name) #tank
基于双下划线的查询
正向查询
# 查询书籍为三国演义的出版社地址 res = models.Book.objects.filter(title=‘三国演义‘).values(‘publish__addr‘,‘title‘) print(res) #<QuerySet [‘publish__addr‘: ‘东方‘, ‘title‘: ‘三国演义‘]> # 查询书籍为小王子的作者的姓名 res = models.Book.objects.filter(title=‘小王子‘).values(‘authors__name‘) print(res) #<QuerySet [‘authors__name‘: ‘jason‘, ‘authors__name‘: ‘tank‘]> # 查询作者为jason的家乡 res = models.Author.objects.filter(name=‘jason‘).values(‘authordetail__addr‘) print(res) #<QuerySet [‘authordetail__addr‘: ‘上海‘]>
反向查询
# 查询南方出版社出版的书名 res = models.Publish.objects.filter(name=‘南方出版社‘).values(‘book__title‘) print(res) #<QuerySet [‘book__title‘: ‘围城‘, ‘book__title‘: ‘红楼梦‘]> # 查询电话号码为203的作者姓名 res = models.AuthorDetail.objects.filter(phone=203).values(‘author__name‘) print(res) #<QuerySet [‘author__name‘: ‘六角恐龙‘]> # 查询作者为jason的写的书的名字 res = models.Author.objects.filter(name=‘jason‘).values(‘book__title‘) print(res) #<QuerySet [‘book__title‘: ‘围城‘, ‘book__title‘: ‘小王子‘, ‘book__title‘: ‘三国演义‘]> # 查询书籍为三国演义的作者的电话号码 res = models.Book.objects.filter(title=‘三国演义‘).values(‘authors__authordetail__phone‘,‘authors__name‘) print(res) # <QuerySet [‘authors__authordetail__phone‘: ‘120‘, ‘authors__name‘: ‘jason‘, ‘authors__authordetail__phone‘: ‘149‘, ‘authors__name‘: ‘kevin‘]> # 查询jason作者的手机号 # 正向 res= models.Author.objects.filter(name=‘jason‘).values(‘authordetail__phone‘) print(res) #<QuerySet [‘authordetail__phone‘: ‘120‘]> # 反向 res = models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘) print(res) #<QuerySet [‘phone‘: ‘120‘]> # 查询出版涩为东方出版涩的所有的图书的名字和价格 # 正向 res = models.Publish.objects.filter(name=‘东方出版涩‘).values(‘book__title‘,‘book__price‘) print(res) #<QuerySet [‘book__title‘: ‘小王子‘, ‘book__price‘: Decimal(‘38.00‘), ‘book__title‘: ‘三国演义‘, ‘book__price‘: Decimal(‘199.00‘)]> # 反向 res = models.Book.objects.filter(publish__name=‘东方出版涩‘).values(‘title‘,‘price‘) print(res) #<QuerySet [‘title‘: ‘小王子‘, ‘price‘: Decimal(‘38.00‘), ‘title‘: ‘三国演义‘, ‘price‘: Decimal(‘199.00‘)]> # 查询东方出版社出版的价格大于100的书 # 反向 res = models.Book.objects.filter(price__gt=100,publish__name=‘东方出版涩‘).values(‘title‘) print(res) #<QuerySet [‘title‘: ‘三国演义‘]> # 正向 res = models.Publish.objects.filter(name=‘东方出版涩‘,book__price__gt=100).values(‘book__title‘) print(res) #<QuerySet [‘book__title‘: ‘三国演义‘]>
总结
""" 总结 其实你在查询的时候先把orm查询语句写出来,再看用到的条件是否在当前表内,在就直接获取,不在就按照正向按字段反向按表名来查即可 比如: 1.查询出版社为北方出版社的所有图书的名字和价格 res1 = Publish.objects.filter(name=‘‘).values(‘book__name‘,‘book__price‘) res2 = Book.objects.filter(publish__name=‘‘).values(‘name‘,‘price‘) 2.查询北方出版社出版的价格大于19的书 res1 = Publish.objects.filter(name=‘‘,book__price__gt=19).values(‘book__name‘,‘book__price) """
聚合查询 aggregate
from django.db.models import Max, Min, Count, Sum, Avg # 查询所有书籍的作者个数 res = models.Book.objects.filter(pk=3).aggregate(cont_num=Count(‘authors‘)) print(res) #‘cont_num‘: 4 # 查询所有出版社出版的书的平均价格 res = models.Publish.objects.aggregate(avg_price=Avg(‘book__price‘)) print(res) #‘avg_price‘: 89.665 # 统计东方出版社出版的书籍的个数 res = models.Publish.objects.filter(name=‘东方出版涩‘).aggregate(count_num=Count(‘book__pk‘)) print(res) #‘count_num‘: 2
分组查询(group_by) annotate
# 统计每个出版社出版的书的平均价格 res = models.Publish.objects.annotate(avg_price=Avg(‘book__price‘)).values(‘name‘,‘avg_price‘) print(res) #<QuerySet [‘name‘: ‘南方出版社‘, ‘avg_price‘: 60.83, ‘name‘: ‘东方出版涩‘, ‘avg_price‘: 118.5, ‘name‘: ‘北方出版涩‘, ‘avg_price‘: None]> # 统计每一本书的作者个数 res = models.Book.objects.annotate(count_num=Count(‘authors__pk‘)).values(‘title‘, ‘count_num‘) print( res) # <QuerySet [‘title‘: ‘围城‘, ‘count_num‘: 3, ‘title‘: ‘小王子‘, ‘count_num‘: 2, ‘title‘: ‘红楼梦‘, ‘count_num‘: 1, ‘title‘: ‘三国演义‘, ‘count_num‘: 2]> # 统计出每个出版社卖的最便宜的书的价格 res = models.Publish.objects.annotate(min_price = Min(‘book__price‘)).values(‘name‘,‘min_price‘) print(res) #<QuerySet [‘name‘: ‘南方出版社‘, ‘min_price‘: Decimal(‘55.00‘), ‘name‘: ‘东方出版涩‘, ‘min_price‘: Decimal(‘38.00‘), ‘name‘: ‘北方出版涩‘, ‘min_price‘: None]> # 查询每个作者出的书的总价格 res = models.Author.objects.annotate(sum_price=Sum(‘book__price‘)).values(‘name‘,‘sum_price‘) print(res) #<QuerySet [‘name‘: ‘jason‘, ‘sum_price‘: Decimal(‘292.00‘), ‘name‘: ‘egon‘, ‘sum_price‘: Decimal(‘55.00‘), ‘name‘: ‘tank‘, ‘sum_price‘: Decimal(‘93.00‘), ‘name‘: ‘kevin‘, ‘sum_price‘: Decimal(‘265.66‘), ‘name‘: ‘六角恐龙‘, ‘sum_price‘: None]>
#配置文件配置参数查看所有的orm操作内部的sql语句 LOGGING = ‘version‘: 1, ‘disable_existing_loggers‘: False, ‘handlers‘: ‘console‘: ‘level‘:‘DEBUG‘, ‘class‘:‘logging.StreamHandler‘, , , ‘loggers‘: ‘django.db.backends‘: ‘handlers‘: [‘console‘], ‘propagate‘: True, ‘level‘:‘DEBUG‘, ,
以上是关于模型层的主要内容,如果未能解决你的问题,请参考以下文章
使用片段时 Intellij 无法正确识别 Thymeleaf 模型变量
php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用