python day55
发布时间:2020-12-20 10:39:37 所属栏目:Python 来源:网络整理
导读:今日内容 如何写一个测试脚本? 创建一个test.py文件 from django.test import TestCase ? # Create your tests here. import os ? ? if __name__ == " __main__ " : os.environ.setdefault( " DJANGO_SETTINGS_MODULE " , " settings文件路径 " ) import dja
如何写一个测试脚本?创建一个test.py文件from django.test import TestCase ? # Create your tests here. import os ? ? if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE","settings文件路径") import django django.setup() """在下面就可以写针对某一个py文件的测试代码""" from app01 import models 搞定了!!!模型层13个方法all() filter() get() reverse() order_by() exclude() values() values_list() count() distinct() exists() first() last()
演示表from django.db import models ? # Create your models here. class Book(models.Model): title = models.CharField(max_length=255) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) ? # 库存数 kucun = models.IntegerField(null=True) # 卖出数 maichu = models.IntegerField(null=True) ? publish = models.ForeignKey(to=‘Publish‘) # 默认是跟publish的主键字段做的一对多外键关联 authors = models.ManyToManyField(to=‘Author‘) # 虚拟字段 1.自动创建第三张表 2.帮助orm跨表查询 ? def __str__(self): return self.title ? class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) # email = models.EmailField() # 就是varchar(254) ? def __str__(self): return self.name ? class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to=‘AuthorDetail‘) ? def __str__(self): return self.name class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=64) """ models.py中的模型类__str__方法 必须返回一个字符串形式数据!!! """ def __str__(self): return self.addr 单表操作新增数据# 第一种:有返回值,并且就是当前被创建的数据对象 modles.Book.objects.create(name=‘‘,price=‘‘,publish=‘‘,author=‘‘,create_time=‘2019-5-1‘) # 第二种:先实例化产生对象,然后调用save方法保存 book_obj = models.Book(name=‘‘,create_time=‘2019-5-1‘) book_obj.save() # 2.验证时间格式字段即可以传字符串也可以传时间对象 import datetime ctime = datetime.datetime.now() book = models.Book.objects.create(name=‘‘,create_time=ctime) 删除数据# 1.删除书名为xxx的这本书 queryset方法 res = models.Book.objects.filter(name=‘‘).delete() # 2.删除书名为xxx的这本书 queryset方法 res = models.Book.objects.filter(name=‘‘).first() res.delete() 修改数据# 1.queryset修改 models.Book.objects.filter(name=‘‘).update(price=‘‘) # 2.对象修改 book = models.Book.objects.filter(name=‘‘).first() book.price = 66.66 book.save() # 对象只有保存方法 这样也能实现修改需求 查询数据<1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误 <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <5> order_by(*field): 对查询结果排序(‘-id‘)/(‘price‘) <6> reverse(): 对查询结果反向排序 >>>前面要先有排序才能反向 <7> count(): 返回数据库中匹配查询(QuerySet)的对象数量 <8> first(): 返回第一条记录 <9> last(): 返回最后一条记录 <10> exists(): 如果QuerySet包含数据,就返回True,否则返回False <11> values(*field): 返回一个ValueQuerySet(一个特殊的QuerySet),运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列 <12> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <13> distinct(): 从返回结果中剔除重复纪录 # 必须完全一样才可以去重(意味着带了id就没有意义了) # res = models.Book.objects.all().values(‘name‘).distinct() 先查一个重复的值再去重 双下滑线查询查看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‘,} } 查询价格大于200的书籍res = models.Book.objects.filter(price__gt=200) 查询价格小于200的书籍res = models.Book.objects.filter(price__lt=200) 查询价格大于等于200.22的书籍res = models.Book.objects.filter(price__gte=200.22) 查询价格小于等于200.22的书籍res = models.Book.objects.filter(price__lte=200.22) 查询价格要么是200,要么是300,要么是666.66res = models.Book.objects.filter(price__in=[200,300,666.66]) 查询价格在200到800之间的res = models.Book.objects.filter(price__range=(200,800)) # 两边都包含 查询书籍名字中包含p的res = models.Book.objects.filter(title__contains=‘p‘) # 仅仅只能拿小写p res = models.Book.objects.filter(title__icontains=‘p‘) # 忽略大小写 查询书籍是以三开头的,或者以P结尾的res = models.Book.objects.filter(title__startswith=‘三‘) res1 = models.Book.objects.filter(title__endswith=‘p‘) 查询出版日期是2017的年res = models.Book.objects.filter(create_time__year=‘2017‘) 多表操作图书管理系统表创建
1.一对多的书籍记录增删改查# 针对外键关联的字段 两种添加方式 # 第一种通过publish_id # 第二种通过publish传出版社对象 ? # 删除书籍直接查询删除即可,删除出版社会级联删除 ? # 编辑数据也是两种对应的方式(对象点的方式(这里能点publish和publish_id)最后点save(),queryset方式update()) 2.多对多的书籍与作者的增删改查"""前提:先获取书籍对象,再通过书籍对象点authors来进行书籍作者的增删改查""" # 1.给书籍新增作者add # 1.add可以传作者id,也可以直接传作者对象,并且支持传多个位置参数(不要混着用) # 2.给书籍删除作者remove # 1.remove同样可以传id,对象,并且支持传多个位置参数(不要混着用) ? # 3.直接清空书籍对象所有的作者数据clear()不用传任何参数 ? # 4.修改书籍对象所关联的作者信息set,注意点set括号内必须传可迭代对象,里面可以传id,对象 """总结:一对多增删改,多对多add,remove,clear,set""" ORM跨表查询基于对象的跨表查询正向查询与反向查询
正向与方向的概念解释# 一对一 # 正向:author---关联字段在author表里--->authordetail 按字段 # 反向:authordetail---关联字段在author表里--->author 按表名小写 ? ? # 一对多 # 正向:book---关联字段在book表里--->publish 按字段 # 反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书 ? # 多对多 # 正向:book---关联字段在book表里--->author 按字段 # 反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书 连续跨表查询
总结:
基于双下划线的查询一对一用连表查询
示例:查询jason作者的手机号# 正向 ret=Author.objects.filter(name=‘jason‘).values(‘authordetail__phone‘) ? # 反向 # 以authordetail作为基表 反向查询,按表名小写 跨表的话,用表名小写 ret=AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘) 示例;查询jason这个作者的性别和手机号# 正向 ret=Author.objects.filter(name=‘jason‘).values(‘sex‘,‘authordetail__phone‘) 示例:查询手机号是130的作者性别# 正向 ret=Author.objects.filter(authordetail__phone=‘13888888‘).values(‘sex‘) ? # 反向 ret=AuthorDetail.objects.filter(phone=‘13888888‘).values(‘author__sex‘) 总结:
示例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 Sum,Max,Min,Avg,Count 示例:models.Book.objects.all().aggregate(Avg("price")) 如果你想要为聚合值指定一个名称,可以向聚合子句提供它models.Book.objects.aggregate(average_price=Avg(‘price‘)) 如果你希望生成不止一个聚合,你可以向
|