以下述模型為基礎,討論檢索對象的方式方法:
from datetime import datefrom django.db import modelsclass Blog(models.Model):name = models.CharField(max_length=100)tagline = models.TextField()def __str__(self):return self.nameclass Author(models.Model):name = models.CharField(max_length=200)email = models.EmailField()def __str__(self):return self.nameclass 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(default=date.today)authors = models.ManyToManyField(Author)number_of_comments = models.IntegerField(default=0)number_of_pingbacks = models.IntegerField(default=0)rating = models.IntegerField(default=5)def __str__(self):return self.headline
比較對象
要比較兩個模型實例,使用標準的 Python 比較操作符
,兩個等號: ==
。實際上,這比較了兩個模型實例的主鍵值。
示例如下,兩個比較是等效的。需要注意的是,有的情況下模型的主鍵可能不是id
,可能是別的字段名稱,但本質都是在比較主鍵。
>>> some_entry == other_entry
>>> some_entry.id == other_entry.id
刪除對象
刪除單個對象實例
刪除方法方便地被命名為delete()
。這個方法立即刪除對象并返回被刪除的對象數以及一個包含每種對象類型的刪除數的字典。
>>> e.delete()
(1, {'blog.Entry': 1})
批量刪除對象實例
所有 QuerySet
都有個 delete()
方法,它會刪除 QuerySet
中的所有成員。
>>> Entry.objects.filter(pub_date__year=2005).delete()
(5, {'webapp.Entry': 5})
要刪除某個模型的所有對象,要查詢得到包含所有對象的 QuerySet
,在QuerySet
上使用 delete()
方法
Entry.objects.all().delete()
如何復制模型實例
新建一個模型實例,保存后,將 pk 設置為 None 并將 _state.adding 設置為 True,再次保存就實現了“復制”。
blog = Blog(name="My blog", tagline="Blogging is easy")
blog.save() # blog.pk == 1blog.pk = None
blog._state.adding = True
blog.save() # blog.pk == 2
如果模型繼承自另一個模型,則還要將id設置為None。
class ThemeBlog(Blog):theme = models.CharField(max_length=200)django_blog = ThemeBlog(name="Django", tagline="Django is easy", theme="python")
django_blog.save() # django_blog.pk == 3django_blog.pk = None
django_blog.id = None
django_blog._state.adding = True
django_blog.save() # django_blog.pk == 4
如果模型還有 ManyToManyField 關聯關系,OneToOneField 關聯關系,要重新配置。
批量修改對象
通過 update()
統一設置 QuerySet
中的所有對象的某個字段。注意此方法設置非關聯字段和 ForeignKey
字段。要更新非關聯字段,請將新值提供為常數。要更新 ForeignKey
字段,請將新值設置為要指向的新模型實例。
# 更新所有pub_date在2007年的Entry,headline修改為"Everything is the same"。
Entry.objects.filter(pub_date__year=2007).update(headline="Everything is the same")
update()
方法會立即應用,并返回查詢匹配的行數。
對于要更新的 QuerySet
唯一的限制是它只能訪問一個數據庫表:模型的主表。您可以基于相關字段進行過濾,但只能更新模型的主表中的列。
對于調用 update 的情況,還可以使用 F 表達式 來根據模型中另一個字段的值來更新字段。這在根據當前值增加計數器時特別有用。例如,要增加博客中每篇文章的 pingback 計數:
>>> Entry.objects.update(number_of_pingbacks=F("number_of_pingbacks") + 1)
在更新中使用 F() 對象時,不能引入連接。