django 表操作
添加表纪录# 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.DateField() price = models.DecimalField(max_digits=8,decimal_places=2) publish = models.CharField(max_length=32) 方式1book_obj = models.Book(title=‘python web‘,price=29,publish=‘北京出版社‘,pub_date="2012-12-12") book_obj.save() 方式2book_obj = models.Book.objects.create(title="java红宝书",state=True,price=100,publish="苹果出版社",pub_date="2012-12-12") 删除表纪录删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如: model_obj.delete() 按条件删除ret = models.Book.objects.all().filter(price__in=[100,88]).delete() 级联删除在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如: class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __str__(self): # __unicode__ on Python 2 return self.name class Author(models.Model): name = models.CharField(max_length=200) email = models.EmailField() def __str__(self): # __unicode__ on Python 2 return self.name class Entry(models.Model): blog = models.ForeignKey(Blog,on_delete=models.CASCADE) headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() authors = models.ManyToManyField(Author) n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField() def __str__(self): # __unicode__ on Python 2 return self.headline delete b = Blog.objects.get(pk=1) # This will delete the Blog and all of its Entry objects. b.delete() 要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用: Entry.objects.all().delete() 如果不想级联删除,可以设置为: blog = models.ForeignKey(Blog,on_delete=models.SET_NULL,blank=True,null=True) 删除语句 Blog.objects.all().filter(name=‘python_qq‘).delete() 修改表纪录Book.objects.filter(title__startswith="py").update(price=120) update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。 ? 查询表记录查询API1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个, 如果符合筛选条件的对象超过一个或者没有都会抛出错误。 <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <5> order_by(*field): 对查询结果排序 <6> reverse(): 对查询结果反向排序 <8> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 <9> first(): 返回第一条记录 <10> last(): 返回最后一条记录 <11> exists(): 如果QuerySet包含数据,就返回True,否则返回False <12> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 <13> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <14> distinct(): 从返回结果中剔除重复纪录 基于双下划线的模糊查询Book.objects.filter(price__in=[100,200,300]) Book.objects.filter(price__gt=100) Book.objects.filter(price__lt=100) Book.objects.filter(price__range=[100,200]) Book.objects.filter(title__contains="python") Book.objects.filter(title__icontains="python") Book.objects.filter(title__startswith="py") Book.objects.filter(pub_date__year=2012) Entry.objects.get(headline__contains=‘Lennon‘) contains: 表示包含的意思!大小写敏感! icontains: contains的大小写不敏感模式。 startswith和endswith 以什么开头和以什么结尾。大小写敏感! istartswith和iendswith 是不区分大小写的模式。 查询操作练习# 1 # 查询老男孩出版社出版过的价格大于200的书籍 book_list = models.Book.objects.filter(price__gt=200,publish=‘老男孩出版社‘) print(book_list) # 2 # 查询2017年8月出版的所有以py开头的书籍名称 book_list = models.Book.objects.filter(title__startswith=‘py‘,pub_date__year=2017,pub_date__month=8) print(book_list) # 3 # 查询价格为50,100 # 或者150的所有书籍名称及其出版社名称 book_list = models.Book.objects.filter(price__in=[50,100,150]).values_list(‘publish‘,‘title‘) print(book_list) # 4 # 查询价格在100到200之间的所有书籍名称及其价格 book_list = models.Book.objects.filter(price__range=[100,200]).values_list(‘title‘,‘price‘) print(book_list) # 5 # 查询所有人民出版社出版的书籍的价格(从高到低排序,去重) book_list = models.Book.objects.filter(publish=‘人民出版社‘).values_list(‘price‘).distinct().order_by(‘-price‘) print(book_list)
多表操作class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # 与AuthorDetail建立一对一的关系 authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to=‘Author‘,) ? 多对多添加方式book_obj = Book.objects.filter(nid=1).first() alex = Author.objects.create(name=‘alex‘,age=‘20‘,authorDetail_id=1) egon = Author.objects.create(name=‘egon‘,age=‘18‘,authorDetail_id=2) # # # 多对多添加方式 book_obj.authors.add(alex,egon) 跨表查询# 1.基于对象的查询(子查询) """ A-B 关联属性在A表 正向查询 A---------B 反向查询 B---------A """ """ 一对多 """ # 正向查询查字段 # 查询书名为红楼梦的出版社名字 book_obj = Book.objects.filter(title=‘红楼梦‘).first() print(book_obj.publish.name) # 查询关联的出版社对象 # 反向查询查表名_set.all # 查询书名为人民出版社的书名 publish_obj = Publish.objects.filter(name=‘人民出版社‘).first() print(publish_obj.book_set.all()) """ 多对多 """ # 正向查询查字段 # 查询书名为红楼梦的作者名字 book_obj = Book.objects.filter(title=‘红楼梦‘).first() print(book_obj.authors.all()) # 查询关联的作者对象 # 反向查询查表名_set.all # 查询alex写的书名 author_obj = Author.objects.filter(name=‘alex‘).first() print(author_obj.book_set.all()) """ 一对一查询 """ """ A - B 关联属性在A表 正向查询 A - --------B 反向查询 B - --------A """ # 正向查询查字段 # 查询alex作者电话 author_obj = Author.objects.filter(name=‘alex‘).first() print(author_obj.authorDetail.telephone) # 查询关联的作者细节对象 # 反向查询查表名 # 查询电话111的作者 authorDetail_obj = AuthorDetail.objects.filter(telephone=‘111‘).first() print(authorDetail_obj.author.name,authorDetail_obj.author.age) ? # 2.基于双下划线的查询(join) # 正向查询查字段,反向查询查表名告诉orm join # 查询书名为红楼梦的出版社名字(一对多) """ sql: select app3_publish.name from app3_book inner join app3_publish on app3_book.publish_id = app3_publish.nid where app3_book.title=‘红楼梦‘ """ # 方式一 # <QuerySet [{‘publish__name‘: ‘人民出版社‘}]> print(Book.objects.filter(title=‘红楼梦‘).values("publish__name")) # 方式二 print(Publish.objects.filter(book__title=‘红楼梦‘).values( "name")) # <QuerySet [{‘publish__name‘: ‘人民出版社‘}]> # 查询书名为红楼梦的作者名字(多对多) """ sql: select name from app3_author inner join app3_book_authors on app3_author.nid = app3_book_authors.author_id inner join app3_book on app3_book.nid = app3_book_authors.book_id """ # 方式一 # <QuerySet [{‘authors__name‘: ‘alex,egon‘}]> print(Book.objects.filter(title=‘红楼梦‘).values("authors__name")) # 方式二 print(Author.objects.filter(book__title=‘红楼梦‘).values("name")) # 查询alex作者电话 print(Author.objects.filter(name=‘alex‘).values("authorDetail__telephone")) print(AuthorDetail.objects.filter(author__name=‘alex‘).values("telephone")) # 进阶练习 # 查询电话111作者出版过所有书籍及书籍出版社的名称 # 方式1 print( Book.objects.filter( authors__authorDetail__telephone__startswith=‘11‘).values( "title","publish__name")) # 方式2 print( Author.objects.filter( authorDetail__telephone__startswith=‘11‘).values( "book__title","book__publish__name"))
聚合查询from django.db.models import Count,Max,Min,Avg print( Book.objects.all().aggregate( avg_price=Avg("price"),max_price=Max(‘price‘),min_price=Min(‘price‘))) # 返回字典 # 单表分组查询 # 查询每一个省以及对应的员工数 # emp: print(Emp.objects.values("province").annotate(cnt=Count("id"))) # 多表分组查询 # 查询出版社的名称及出版书籍的个数 ret = Publish.objects.values("nid").annotate(cnt=Count("book__title")) print(ret) ret = Publish.objects.values("name").annotate(cnt=Count("book__title")) print(ret) ret = Publish.objects.values("name").annotate( cnt=Count("book__title")).values( "name","cnt") print(ret) # 查询每一个作者的名字以及出版书籍的最高价格 ret = Author.objects.values("pk").annotate( max_price=Max("book__price")).values( "name","max_price") print(ret) # 查询每一个书籍的名称及对应的作者个数 ret = Book.objects.values("pk").annotate( cnt=Count("authors__nid")).values( "title","cnt") print(ret) # 统计每一本以py开头的书籍的作者个数: ret = Book.objects.filter( title__startswith="py").values("pk").annotate( cnt=Count("authors__nid")).values( "title","cnt") print(ret) # (4)统计不止一个作者的图书 ret = Book.objects.values("pk").annotate( cnt=Count("authors__nid")).filter( cnt__gt=1).values( "title","cnt") print(ret) # F查询Q查询 from django.db.models import F,Q # 统计书的评论数大于读过数 ret = Book.objects.filter(comment_num__lt=F("read_num")) print(ret) Book.objects.all().update(price=F("price") + 10) ret = Book.objects.filter(Q(title=‘红楼梦‘) | Q(price__gt=100)) print(ret) ret = Book.objects.filter(~Q(title=‘红楼梦‘) | Q(price__gt=100)) print(ret) ? 操作API
? ?get() get(**kwargs) 返回按照查询参数匹配到的单个对象,参数的格式应该符合Field lookups的要求。 如果匹配到的对象个数不只一个的话,触发MultipleObjectsReturned异常 如果根据给出的参数匹配不到对象的话,触发DoesNotExist异常。例如: ? bulk_create() bulk_create(objs,batch_size=None) 以高效的方式(通常只有1个查询,无论有多少对象)将提供的对象列表插入到数据库中: Entry.objects.bulk_create([ ... Entry(headline=‘This is a test‘),... Entry(headline=‘This is only a test‘),... ]) 注意事项:
? count() 返回在数据库中对应的QuerySet对象的个数。count()永远不会引发异常。 ? latest(field_name=None) 使用日期字段field_name,按日期返回最新对象。 下例根据Entry的‘pub_date‘字段返回最新发布的entry: Entry.objects.latest(‘pub_date‘) exists() 如果QuerySet包含任何结果,则返回True,否则返回False。 查找具有唯一性字段(例如primary_key)的模型是否在一个QuerySet中的最高效的方法是: entry = Entry.objects.get(pk=123) if some_queryset.filter(pk=entry.pk).exists(): print("Entry contained in queryset") 它将比下面的方法快很多,这个方法要求对QuerySet求值并迭代整个QuerySet: if entry in some_queryset: print("Entry contained in QuerySet") 若要查找一个QuerySet是否包含任何元素: if some_queryset.exists(): print("There is at least one object in some_queryset") 将快于: if some_queryset: print("There is at least one object in some_queryset") 查询参数及聚合函数http://www.liujiangblog.com/course/django/132 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |