Django ORM 多對多操作 使用聚合函數和分組 F查詢與Q查詢


創建表

 
# models.py

form django.db import models

class Book(models.Model):  # 表名book,django會自動使用項目名+我們定義的表名
  # 如沒有自定義主鍵,django會自動添加一個主鍵,字段名id 自增
  name = models.CharField(max_length=20)  # 字段名name 類型 vachar(20)
  price = models.IntegerField()   # 字段名price 類型int
  pub_date = models.DateField()   # 字段名pub_date 類型 date (時間戳)
  publish = models.ForeighKey('Publish')  # 創建外鍵關聯到Publish表的id字段,django會自動將該名稱改為publish_id  
# 如果這樣寫 publish = models.ForeighKey(Publish) 括號內無引號,則必須將Publish類放到Book類的上面
  authors = models.ManyToManyField('Author',related_name='xxx')  將book與author表做多對多關系 related_name 同一對多中的說明
  # django會自動創建一張表(book與author的中間關聯表)名稱為appname_book_authors
  def __str__(self):
    return self.name  # 打印實例對象時顯示為self.name


#class Book_Author(models.Model):  自己創建第三張表
#  book = models.ForeignKey('book')
#  author = models.ForeignKey('Author')

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

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

  def __str__(self):
    return self.name  
 

多對多的添加設置刪除

 
# views.py

from django.shortcuts import render
from app_name.models import *  # 導入models.py

def add(request):  # 增加數據的視圖函數
  # 系統自己創建的第三張表使用創建對象操作
book_obj = Book.objects.get(id=4)  # 取出id為4的書
  # book_obj.authors.all()  此時取出的是一個空的集合
  authors_obj = Author.objects.all()  # 取出所有author名稱的集合
  book_obj.authors.add(*author_obj)  # 將所有作者添加到這本書中
  book_obj.authors.remove(*author_obj) # 將所有作者從書中刪除
  book_obj.authors.add(2) # 將id為2的作者添加到此書
  book.obj.authors.add([1,2])  # 將id為1和2的作者添加到此書
  book_obj.authors.remove(1) # 將id為1的作者從書中刪除
book_obj.authors.clear() # 清除此書所有的作者
book_obj.authors.set([2,3,4]) # 將書的作者設置為id為2,3,4的作者 (相當於重新設置)
  

# 我們自己定義的第三張表(不常用)
  Book_Author.objects.create(book_id=2, author_id=3)
  
obj = Book.objects.get(id=2)
obj.book_author_set.all()[0]l.author
  

  return HttpResponse('xxx')
 

多對多的查詢

 
# 怎么使用多對多查詢呢?
book_obj = Book.objects.get(name='python')
print(book_obj.name)  # python
print(book_obj.authors.all())  # QuerySet  返回一個QuerySet對象,里面是author的實例集合
print(type(book_obj.authors.all()))  # <class 'django.db.models.query.QuerySet'>

1、查詢作者id為2出的所有的書
author_obj=Author.objects.get(id=2)
author_obj.book_set.all()

2、查詢三班所對應的所有老師
obj = Classes.objects.filter(name='三班').first()  從班級表取出三班
obj.m.all()  # 從三班中取所有的老師 m表示多對多關系的名稱

還是通過雙下划線
2、查詢作者alex出的所有書
Book.objects.filter(authors__name='alex').values('name','price')
 

使用聚合函數和分組

# views.py

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

# 聚合函數
# 取出所有書總價格的平均值
Book.objects.all().aggregate(Avg('price'))  # 必須使用aggregate函數
# 取alex出的書的總價格
Book.objects.filter(author__name='alex').aggregate(alex_money=Sum('price'))  # {'alex_money':166}
# 取alex出的書的數量
Book.objects.filter(author__name='alex').aggregate(alex_count=Count('price'))  # {'alex_count':2}

# 分組
# 每一個作者出的書的總價
Book.objexts.values('author__name').annotate(Sum('price'))  # QuerySet [{'price__sum':211, 'authors__name':'alex'},...]
# 查每個出版社最便宜書的價格
Publish.bojects.values('name').annotate(Min('book__price'))

F查詢和Q查詢

針對的問題:1、在filter中定義的條件只能是and操作沒有or和not   2、如果要將所有書的價格都加上10 用price=price+10是不行的

from django.db.models import Q,F
#第一個問題
Book.objects.filter(Q(price=87)|Q(name='linux'))  # select * from book where (price=87 or name='linux')
Book.objects.filter(~Q(name='linux'))  # select * from book where name != 'linux'
#第二個問題
Book.objects.all().update(price=F('price')+10)

關鍵字查詢與F,Q查詢一起使用時,必須將F,Q查詢放在前面
Book.objects.filter(Q(name='Go'),price=87)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM