Django之Making queries

from django.db import models
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)
  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

以下內(nèi)容將以上述代碼為例子說明

1.創(chuàng)建類

為了在python類中表示數(shù)據(jù)庫表單數(shù)據(jù),django使用一個(gè)直覺的系統(tǒng): 一個(gè)model類代表一個(gè)數(shù)據(jù)庫表,一個(gè)實(shí)例代表數(shù)據(jù)庫表中一個(gè)特定的記錄。為了創(chuàng)建一個(gè)對象,通過關(guān)鍵字參數(shù)實(shí)例化,然后調(diào)用save()方法保存到數(shù)據(jù)庫中。

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

2.Saving changes to objects

為了保存已存在數(shù)據(jù)庫中的對象的變化,使用save().

b5.name = 'New name'
b5.save()

3. Saving ForeignKey and ManyToManyField fields

 from blog.models import Entry
 entry = Entry.objects.get(pk=1)
 cheese_blog = Blog.objects.get(name="Cheddar Talk")
 entry.blog = cheese_blog
 entry.save()

更新一個(gè)many-to-many字段有些不一樣的地方,在字段上使用add()方法來在關(guān)系上增加一個(gè)記錄.

 from blog.models import Author
 joe = Author.objects.create(name="Joe")
 entry.authors.add(joe)

如果在一次add中增加多個(gè)記錄,傳入多個(gè)參數(shù),

 john = Author.objects.create(name="John")
 paul = Author.objects.create(name="Paul")
 george = Author.objects.create(name="George")
 ringo = Author.objects.create(name="Ringo")
 entry.authors.add(john, paul, george, ringo)

4.檢索類

為了檢索類,通過model類上的管理器構(gòu)造一個(gè)QuerySet,一個(gè)A QuerySet 代表數(shù)據(jù)庫的一個(gè)集合類,它可以有0個(gè)或者多個(gè)filters. Filters基于給定的參數(shù)縮小查詢結(jié)果,在SQL中一個(gè)QuerySet 相當(dāng)于一個(gè)select語句, 一個(gè) filter相當(dāng)于一個(gè)limiting 子句比如 WHERE 或者 LIMIT.

 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."

管理器是一個(gè)model的QuerySet的主要來源,例如, Blog.objects.all() 返回一個(gè)包含所有Blog類的
QuerySet。檢索一個(gè)數(shù)據(jù)庫表中所有的類,使用Manager的all()
all_entries = Entry.objects.all()
為了返回一個(gè)子集,可以增加附加filter條件,常用的有以下兩種:

  • filter(**kwargs) 返回一個(gè)新的QuerySet包含匹配到給定查詢參數(shù)的類。
  • exclude(**kwargs) 返回一個(gè)新的QuerySet包含沒有匹配到給定查詢參數(shù)的類。
    舉例:
    Entry.objects.filter(pub_date__year=2006)' 和Entry.objects.all().filter(pub_date__year=2006)`一樣
    同樣,我們可以使用filter鏈在,復(fù)雜查詢中
>>> Entry.objects.filter(
... headline__startswith='What'
...   ).exclude(
... pub_date__gte=datetime.date.today()
...   ).filter(
... pub_date__gte=datetime(2005, 1, 30)
... )

:1.每次查詢返回的QuerySet都是不同的,2.QuerySet是懶惰的
就是說

q = Entry.objects.filter(headline__startswith="What")
q = q.filter(pub_date__lte=datetime.date.today())
q = q.exclude(body_text__icontains="food")
print(q)

只有最后一個(gè)語句才會(huì)進(jìn)行數(shù)據(jù)庫操作。
使用get()方法檢索一個(gè)單一的類,filter() 方法總是給你一個(gè) QuerySet, 即使只有一個(gè)單一的類匹配到查詢條件,這種情況下,返回的結(jié)果是一個(gè)只有一個(gè)元素的QuerySet.如果你知道只有一個(gè)結(jié)果匹配到查詢,你可以使用get()方法,該方法直接返回結(jié)果類。>>> one_entry = Entry.objects.get(pk=1),注意,如果沒有結(jié)果匹配到查詢條件,get()會(huì)報(bào)DoesNotExist的錯(cuò)誤,同樣,當(dāng)查詢結(jié)果多于一個(gè)時(shí),也會(huì)報(bào)錯(cuò),MultipleObjectsReturned。

5.Limiting QuerySets

Entry.objects.all()[:10:2]
Entry.objects.order_by('headline')[0]

6.Field lookups

基本查詢關(guān)鍵字參數(shù)使用以下形式:field__lookuptype=value.相當(dāng)于sql查詢語句中的where子句。
舉例:

Entry.objects.filter(pub_date__lte='2006-01-01')
#-->
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';
Entry.objects.get(headline__exact="Cat bites dog")
#-->
SELECT ... WHERE headline = 'Cat bites dog';
Blog.objects.get(name__iexact="beatles blog")
 #:  不區(qū)分大小寫的匹配。
Entry.objects.get(headline__contains='Lennon')
 #: 有大小寫區(qū)分的包含測試
startswith, endswith Starts-with and ends-with search,

7,Comparing objects

為了比較兩個(gè)Model對象實(shí)例,使用==即可。后臺,將會(huì)進(jìn)行對比兩個(gè)model的主鍵

8.Deleting objects

>>> e.delete()
(1, {'weblog.Entry': 1})

每個(gè)QuerySet都有一個(gè)delete()方法,你可以在查詢后調(diào)用delete方法。

9.Copying model instances

盡管還沒有內(nèi)建的方法用來復(fù)制model實(shí)例,創(chuàng)建一個(gè)所有字段值都復(fù)制的新的實(shí)例也是很容易的,最簡單的情況是,設(shè)置pk為None,

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

many-to-many情況

entry = Entry.objects.all()[0] # some previous entry
old_authors = entry.authors.all()
entry.pk = None
entry.save()
entry.authors.set(old_authors)

one-to-one情況

detail = EntryDetail.objects.all()[0]
detail.pk = None
detail.entry = entry
detail.save()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容