Django ORM 一對一,一對多,多對多, 添加,批量插入和查詢 F與Q添加


模型類

class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32, default=None) create_time = models.DateTimeField() price = models.DecimalField(decimal_places=2, max_digits=8, default=None) publish_id = models.ForeignKey(to="Publish", on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') def __str__(self): return str(self.nid) + ':' + self.title class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) email = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() email = models.CharField(max_length=32) ad = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE) class AuthorDetail(models.Model): address = models.CharField(max_length=32) telephone = models.IntegerField()

批量插入

book_list = [] for i in range(100): book = Book(title='book_%s' % i, price=i * i) book_list.append(book) Book.objects.bulk_create(book_list)

 

一對多和多對多 添加操作

# 一對多添加用戶

publish = Publish.objects.get(nid=1)

Book.objects.create(

  title='ubuntu',

  price=122,

  create_time='2012-2-2',

  publish_id=publish,

  # publish_id_id=publish.nid )

# 多對多添加用戶

author01 = Author.objects.get(id="1")

author02 = Author.objects.get(id="2")

book = Book.objects.get(nid='2')

# book.authors.add(author01, author02)

# 多對多第二種 

book.authors.add(1, 2)

# 多對多第三種

book.authors.add(*[1, 2])

# 刪除關聯的作者

book.authors.remove(author01)

# 刪除所有關聯的作者

book.authors.clear()

# 先刪除所有在綁定

book.authors.set(1)

查詢操作

基於對象的跨表查詢(基於子查詢)

    # 一對多查詢
    # 正查
    book = Book.objects.get(nid='1') # 取到關聯的對象
    publish = book.publish_id print(publish.name) # 反查
    publish = Publish.objects.get(nid='1') books = publish.book_set.all() # 多對多查詢
    book = Book.objects.get(nid='1') authors = book.authors.all() author = Author.objects.get(id='1') book = author.book_set.all() # 一對一
    author = Author.objects.get(id='1') ad = author.ad author_detail = AuthorDetail.objects.get(id='1') author = author_detail.author

# 基於雙下划線的跨表查詢(基於join實現的)
# KEY:正向查詢按字段,反向查詢按表明小寫

    # linux這本書的出版社名字
    # 正向
    name = Book.objects.filter(title='linux').values('publish_id__name') # 反向
    name = Publish.objects.filter(book__title='linux').values('name') # 查詢第一個出版社對用的所有書
    # 正向
    book = Publish.objects.filter(nid='1').values('book__title') # 反向
    book = Book.objects.filter(publish_id_id='1').values('title') # 查詢Linux這本書所有作者的手機號
    telephone = Book.objects.filter(title='linux').values('authors__ad__telephone') telephone = Author.objects.filter(book__title='linux').values('ad__telephone') # 查詢id=1的出版社的作者的書籍和作者的名字
    title_name = Publish.objects.filter(nid='1').values('book__authors__name', 'book__title') title_name = Book.objects.filter(publish_id_id=1).values('title', 'authors__name') # 查詢作者手機號的開頭為110的書籍和出版社名稱
    title_name = Author.objects.filter(ad__address__startswith='北京').values('book__title', 'book__publish_id__name')

# 聚合和分組

 from django.db.models import Avg, Max, Sum, Min, Count avg = Book.objects.all().aggregate(price=Avg('price')) # 單表分組查詢 # 查詢每個出版社id以及對應大的書籍個數 count = Book.objects.values('publish_id').annotate(count=Count(1)) # values中的值為分類的參數 ''' select Count(1) from Book GROUP by publish_id ''' # 跨表分組查詢 # 查看每一個出版社名稱以及對應的書籍個數 count = Book.objects.values('publish_id__name').annotate(count=Count(1)) count = Publish.objects.values('name').annotate(c=Count('book__nid')) # 查找作者大於一個的書籍對應的作者數 query = Book.objects.annotate(c=Count('authors')).filter(c__gt=1).values('c', 'title')

 

F與Q

F 比較兩列大小

Q 兩個關系用 與或非 表示

  # F與Q查詢
    from django.db.models import F, Q # 查詢評論數大於點贊數的書籍名稱 title = Book.objects.filter(commit_count__gt=F('poll_count') * 1).values('title') # 讓所有的書籍價格加100 price = Book.objects.update(price=F('price') + 100) # 取出評論大於20或者點贊數小於10 ret = Book.objects.filter(Q(commit_count__gt=20) | ~Q(poll_count__gt=10)) # 取價格在等於20或者評論數大於20且點贊數小於10的 ret = Book.objects.filter(Q(Q(price=20) | Q(commit_count__gt=20)) & ~Q(poll_count__gt=10)) ret = Book.objects.filter(Q(Q(price=20) | Q(commit_count__gt=20)), ~Q(poll_count__gt=10))

 

Q的添加操作

q = Q() #添加的元素關系為或 q.connertor ="or" #添加查詢條件 q.children.append(("name","123")) q.children.append("age","12")

 


免責聲明!

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



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