Django數據操作


1.一個模型類代表數據庫中的一個表,一個模型類的實例代表這個數據庫表中的一條特定的記錄。

2.管理器和查詢集。

  • 查詢集QuerySet表示從數據庫中取出來的對象的集合。它可以含有零個、一個或者多個過濾器。過濾器基於所給的參數限制查詢的結果。查詢集有可迭代和可切片的特點。
  • 每個模型都至少有一個管理器,它默認命名為objects管理器只可以通過模型的類訪問,而不可以通過模型的實例訪問,目的是為了強制區分“表級別”的操作和“記錄級別”的操作。
>>>Blog.objects
<django.db.models.manager.Manager object at ...>
>>> b = Blog(name='Foo', tagline='Bar')
>>> b.objects
Traceback:
    ...
AttributeError: "Manager isn't accessible via Blog instances."

3.創建、更改,並保存一個實例

 from blog.models import Blog
 b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
 b.save()
b.name = 'New name'
b.save()

  注意:在調用b.save()時,Django才正真訪問數據庫。

  也可以使用管理器的create方法,一步創建和保存。

p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
  • 更新ForeignKey 字段的方式和保存普通字段相同 —— 只要把一個正確類型的對象賦值給該字段。
  • 更新ManyToManyField 的方式有一些不同 —— 需要使用字段的add()方法來增加關聯關系的一條記錄。為了在一條語句中,向ManyToManyField添加多條記錄,可以在調用add()方法時傳入多個參數
from blog.models import Author
joe = Author.objects.create(name="Joe")
entry.authors.add(joe)

  可以使用update() 方法為一個查詢集中所有對象的某個字段都設置一個特定的值。

# Update all the headlines with pub_date in 2007.
Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

4.獲取對象(大多數情況下,需要從數據庫中查找對象時,會使用all()、 get()filter() 和exclude()。 然而,這只是冰山一角;查詢集方法的完整列表,請參見查詢集API 參考https://docs.djangoproject.com/en/1.10/ref/models/querysets/。

  • 獲取所有對象
all_blogs = Blog.objects.all()

  all()方法返回包含數據庫中所有對象的一個查詢集

  • 可以使用filter(**kwargs),exclude(**kwargs)設置過濾條件,返回一個新的查詢子集。
Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.date.today())
  • 每次篩選一個查詢集,得到的都是全新的另一個查詢集,它和之前的查詢集之間沒有任何綁定關系。每次篩選都會創建一個獨立的查詢集,它可以被存儲及反復使用。如下:這三個查詢集都是獨立的。
>>> q1 = Entry.objects.filter(headline__startswith="What")
>>> q2 = q1.exclude(pub_date__gte=datetime.date.today())
>>> q3 = q1.filter(pub_date__gte=datetime.date.today())
  • 查詢集 是惰性執行的 —— 創建查詢集不會帶來任何數據庫的訪問。直到查詢集需要求值時,Django 才會真正運行這個查詢。
  • 可以使用字段查詢,指定字段范圍,形式為field__lookuptype=value(中間是兩個下划線)。
Entry.objects.filter(pub_date__lte='2006-01-01')
Entry.objects.get(headline__exact="Man bites dog")
Blog.objects.get(name__iexact="beatles blog")
Entry.objects.get(headline__contains='Lennon')

  大約有二十多種查詢的類型。查詢條件中指定的字段必須是模型字段的名稱。但有一個例外,對於ForeignKey你可以使用字段名加上_id 后綴。

Entry.objects.filter(blog_id=4)
  • 多表關聯查詢:Django 提供一種強大而又直觀的方式來“處理”查詢中的關聯關系,只需使用關聯的模型字段的名稱,並使用雙下划線分隔。
#from django.db import models

#class Blog(models.Model):
#    name = models.CharField(max_length=100)

#class Author(models.Model):
#    name = models.CharField(max_length=50)
   
#class Entry(models.Model):
#    blog = models.ForeignKey(Blog)
#    authors = models.ManyToManyField(Author)
 
Entry.objects.filter(blog__name='Beatles Blog')

 這種跨越可以是任意的深度。它還可以反向工作。若要引用一個“反向”的關系,只需要使用該模型的小寫的名稱。

Blog.objects.filter(entry__headline__contains='Lennon')
  • 如果知道只有一個對象滿足你的查詢,可以使用管理器get() 方法,它直接返回該對象:
one_blog = Blog.objects.get(pk=1)

  如果沒有結果滿足查詢,get() 將引發一個DoesNotExist 異常。類似地,如果有多條記錄滿足get() 的查詢條件,Django 也將報錯。這種情況將引發MultipleObjectsReturned異常。

  • 可以使用切片和索引限制查詢集。
#切片
Blog.objects.all()[5:10]
Blog.objects.all()[:10:2]
#索引
Blog.objects.order_by('headline')[0]

  通常,查詢集 的切片返回一個新的查詢集 —— 它不會執行查詢。有一個例外,是如果你使用Python 切片語法中"step"參數。

  • 其他常用的查詢API包括:
    • order_by:對查詢結果排序。
    • reverse:對查詢結果反向排序。
    • distinct:從返回結果中剔除重復記錄。
    • values:返回一個ValuesQuerySet —— QuerySet 的一個子類,迭代時返回字典而不是模型實例對象。
    • values_list:與values() 類似,只是在迭代時返回的是元組而不是字典。
    • count:返回在數據庫中對應的 QuerySet.對象的個數。
    • first,last,earliest,latest:返回QuerySet.對象的第一、最后、最早、最近的一條記錄。
    • exists:如果QuerySet 包含任何結果,則返回True,否則返回False
  • 聚合函數和分組函數:
    • aggregate()QuerySet 的一個終止子句,意思是說,它返回一個包含一些鍵值對的字典。鍵的名稱是聚合值的標識符,值是計算出來的聚合值。
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(average_price=Avg('price'), Max('price'), Min('price'))
{'average_price': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
    • 逐個對象的匯總結果可以由annotate()子句生成。annotate()子句被指定之后,QuerySet中的每個對象都會被注上特定的值。與 aggregate() 不同的是, annotate() 不是一個終止子句。annotate()子句的返回結果是一個查詢集 (QuerySet);這個 QuerySet可以用任何QuerySet方法進行修改,包括 filter()order_by(), 甚至是再次應用annotate()
# Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1
    • 在聚合函數中指定聚合字段時,Django 允許你使用同樣的 雙下划線 表示關聯關系;也同樣可以用關聯模型的小寫名稱和雙下划線表示"反轉"關系。
  • 使用Q 對象進行復雜的查詢:Q 對象可以使用& 和| 操作符組合起來,可以使用~ 操作符取反,這允許組合正常的查詢和取反(NOT) 查詢。

Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
  • 比較對象:為了比較兩個模型實例,只需要使用標准的Python 比較操作符,即雙等於符號:==在后台,它會比較兩個模型主鍵的值。

 5.刪除對象

  delete()方法將立即刪除對象且沒有返回值。 

Entry.objects.filter(pub_date__year=2005).delete()

   注意,delete() 是唯一沒有在管理器 上暴露出來的查詢集方法。這是一個安全機制來防止你意外地請求Entry.objects.delete(),而刪除所有 的條目。如果你確實想刪除所有的對象,你必須明確地請求一個完全的查詢集:

Entry.objects.all().delete()

6.復制對象

  最簡單的方法是,只需要將pk 設置為None。 

blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1

blog.pk = None
blog.save() # blog.pk == 2

  

 

 


免責聲明!

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



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