?
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、雅安服務(wù)器托管、營(yíng)銷軟件、網(wǎng)站建設(shè)、賀州網(wǎng)站維護(hù)、網(wǎng)站推廣。
目錄
queries:...1
exclude():...3
關(guān)聯(lián)對(duì)象查詢:...3
反向查詢對(duì)
復(fù)雜查詢:...4
保存ForeignKey和ManyToMany字段:...5
QuerySet鏈?zhǔn)竭^濾:...5
lookup,高級(jí)條件過濾:...5
跨關(guān)聯(lián)關(guān)系查詢:...6
限制返回個(gè)數(shù):...6
查詢對(duì)象比較...7
不常用查詢API:...7
事務(wù):...10
自定義管理器:...11
?
?
?
?
user.groups.set(groups)
user.groups.all()
group.user_set.all()?? #反查會(huì)加上_set
?
Author.objects.exclude(name='jowin')
?
Entry.objects.get(id=1).blog?? #一對(duì)多,前向查詢,通過屬性訪問關(guān)聯(lián)的(外部)對(duì)象
Blog.objects.get(id=1).entry_set.all()?? #一對(duì)多,反向查詢,模型中有fk,該fk所指的模型實(shí)例可通過一個(gè)管理器返回前一個(gè)模型的所有實(shí)例,默認(rèn)這個(gè)管理器的名字是
?
?
例:
class Group(models.Model):
??? name = models.CharField(max_length=20)
?
??? def __str__(self):
??????? return self.name
?
class User(models.Model):
??? name = models.CharField(max_length=20)
?? ?groups = models.ManyToManyField(Group)?? #ManyToMany會(huì)自動(dòng)生成中間表publish_user_groups
?
??? def __str__(self):
??????? return self.name
?
>>> from publish.models import Group,User
>>> user = User.objects.create(name='jowin')
>>> group1 = Group.objects.create(name='magedu1')
>>> group2 = Group.objects.create(name='magedu2')
>>> user = User.objects.first()
>>> groups = Group.objects.all()
>>> type(groups)
>>> user.groups.set(groups)?? #將用戶為'jowin'加入多個(gè)組里
>>> user.groups.all()
>>> group = Group.objects.get(id=1)
>>> group.user_set.all()?? #反查會(huì)加上_set
?
?
例,多對(duì)多,自己加中間表:
class Group(models.Model):
??? name = models.CharField(max_length=20)
?
??? def __str__(self):
??????? return self.name
?
class User(models.Model):
??? name = models.CharField(max_length=20)
??? # groups = models.ManyToManyField(Group)
?
??? def __str__(self):
??????? return self.name
?
class UserGroupRelation(models.Model):?? #多對(duì)多,自己加中間表
??? user = models.ForeignKey(User)
??? group = models.ForeignKey(Group)
?
sqlite> .schema publish_usergrouprelation
CREATE TABLE IF NOT EXISTS "publish_usergrouprelation" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "group_id" integer NOT NULL REFERENCES "publish_group
" ("id"), "user_id" integer NOT NULL REFERENCES "publish_user" ("id"));
CREATE INDEX "publish_usergrouprelation_group_id_e393f98c" ON "publish_usergrouprelation" ("group_id");
CREATE INDEX "publish_usergrouprelation_user_id_0e041f81" ON "publish_usergrouprelation" ("user_id");
sqlite> .schema publish_group
CREATE TABLE IF NOT EXISTS "publish_group" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(20) NOT NULL);
sqlite> .schema publish_user
CREATE TABLE IF NOT EXISTS "publish_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(20) NOT NULL);
?
?
例:
class Blog(models.Model):
??? name = models.CharField(max_length=100)
??? tagline = models.TextField()
?
??? def __str__(self):
??????? return self.name
?
class Author(models.Model):
??? name = models.CharField(max_length=50)
??? email = models.EmailField()
?
??? def __str__(self):
??????? 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()
??? authors = models.ManyToManyField(Author)
??? n_comments = models.IntegerField()
??? n_pingbacks = models.IntegerField()
??? rating = models.IntegerField()
?
??? def __str__(self):
??????? return self.headline
?
例:
?
?
與filter相反:
>>> b = Blog(name='beatles blog', tagline='all the latest beatles news')
>>> b.save()
>>> a1 = Author.objects.create(name='jowin',email='jowin@ane56.com')
>>> a2 = Author.objects.create(name='mage',email='mage@ane56.com')
>>> Author.objects.exclude(name='jowin')
?
?
>>> e = Entry(blog=Blog.objects.get(id=1),headline='test',body_text='test',pub_date=timezone.now(),n_comments=20,n_pingbacks=50,rating=100)
>>> e.save()
>>> e = Entry.objects.get(id=1)
>>> e.blog?? #一對(duì)多,前向查詢,通過屬性訪問關(guān)聯(lián)的(外部)對(duì)象
>>> e.authors.set(Author.objects.all())
>>> e.authors.all()
?
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.all()?? #一對(duì)多,反向查詢,模型中有fk,該fk所指的模型實(shí)例可通過一個(gè)管理器返回前一個(gè)模型的所有實(shí)例,默認(rèn)這個(gè)管理器的名字是
>>> b.entry_set.filter(headline__contains='test')
>>> b.entry_set.count()
1
?
?
class Entry(models.Model):
???????? blog = models.ForeignKey(Blog, related_name='entries')
使用時(shí)用entries_set;
?
?
filter中的關(guān)鍵字參數(shù)默認(rèn)是AND的關(guān)系;
若用OR的關(guān)系,得用Q對(duì)象(from django.db.models import Q),Q對(duì)象用于封裝一組關(guān)鍵字參數(shù);
查詢函數(shù)get、filter、exclude中可混合使用Q對(duì)象和關(guān)鍵字參數(shù),所有提供給查詢函數(shù)的參數(shù)都將AND在一起,注意Q對(duì)象要在關(guān)鍵字參數(shù)前,如Poll.objects.get(Q(question__startswith='who'),Q(pub_date=date(2019,1,8)|Q(pub_date=date(2019,1,2)),Poll.objects.get(Q()|Q(),question__startswith='who');
推薦用符號(hào)&和|;
>>> from django.db.models import Q
>>> Author.objects.filter(Q(name='jowin')|Q(name='mage'))
?
?
>>> e = Entry.objects.create(blog=b,headline='test2',body_text='test2',pub_date=timezone.now(),n_comments=30,n_pingbacks=60,rating=90)
>>> e.blog
>>> e.blog = b
>>> a3 = Author.objects.create(name='mage2',email='mage2@magedu.com')
>>> a4 = Author.objects.create(name='jowin2',email='jowin2@magedu.com')
>>> e.authors = [a3]
>>> e.save()
>>> e.authors.add(a3,a4)?? #e.authors.set([])清空
>>> e.save()
>>> e.authors.create(name='mage3',email='mage3@magedu.com')?? #查詢創(chuàng)建fk的value
?
?
Entry.objects.filter(headline__startswith='what').exclude(pub_date__gte=datetime.date.today()).filter(pub_date__gte=datetime(2019,1,8))
?
?
使用
gt、gte、lt、lte
contains?? #包含
exact?? #精確匹配,默認(rèn)
startswith?? #開始于
endswith?? #結(jié)束于
regex??? #RE
icontains、iexact、istartswith、iendwith、iregex?? #忽略大小寫
in?? #在列表中
range?? #范圍之內(nèi)
date、year、month、day?? #時(shí)間日期類型
?
>>> Entry.objects.filter(pub_date__gt='2018-12-31')
>>> Blog.objects.get(name__iexact='beatles blog')
>>> Blog.objects.filter(pk__in=[0,2,4])
>>> Entry.objects.filter(pub_date__range=(datetime.date(2018,12,31),datetime.date(2019,1,9)))
>>> Entry.objects.get(body_text__regex=r'^test2')?? #
?
?
>>> Entry.objects.filter(blog__name='beatles blog')
>>> Blog.objects.filter(entry__headline__contains='test')?? #反向
>>> Blog.objects.filter(entry__authors__name__isnull=True)?? #多層
>>> Blog.objects.filter(entry__authors__isnull=False,entry__authors__name__isnull=True)?? #多個(gè)過濾條件
?
>>> from django.db.models import F?? #模型字段查詢F,通常是將模型字段與常量比較,或比較2個(gè)字段值
>>> Entry.objects.filter(n_pingbacks__gt=F('n_comments'))?? #點(diǎn)贊數(shù)大于評(píng)論數(shù)
>>> Entry.objects.filter(rating__gt=F('n_comments') + F('n_pingbacks'))
?
?
>>> Entry.objects.all()[:3]?? #同limit 5
>>> Entry.objects.all()[1:2]?? #同offset 1 limit 1
?
?
查詢對(duì)象比較,用==,在后臺(tái)比較的是2個(gè)模型主鍵的值:
some_entry == other_entry?? #some_entry.id == other_entry.id
?
?
https://docs.djangoproject.com/en/2.1/ref/models/querysets/
?
annotate():
添加注釋屬性,與聚合函數(shù)一起使用,返回聚合值;
>>> from blog.models import Blog,Author,Entry
>>> from django.db.models import Count
>>> q = Blog.objects.annotate(Count('entry'))
>>> q
>>> q[0].name
'beatles blog'
>>> q[0].entry__count
1
>>> qs = Blog.objects.annotate(entry_num=Count('entry'))
>>> for q in qs:
...???? print(q.entry_num)
...
1
1
?
?
aggregate():
聚合函數(shù),返回是字典;
>>> qs = Blog.objects.aggregate(Count('entry'))
>>> qs
{'entry__count': 2}
>>> qs = Blog.objects.aggregate(entry_num=Count('entry'))
>>> qs
{'entry_num': 2}
?
?
聚合類函數(shù):
from django.db.models import Avg,Count,Max,Min,StdDev(標(biāo)準(zhǔn)除),Sum,Variance(方差)
聚合類函數(shù)配合聚合函數(shù)aggregate()或注釋函數(shù)annotate()使用;
?
?
distinct():
去重;
>>> Author.objects.distinct()
>>> Entry.objects.order_by('blog')
>>> Entry.objects.order_by('pub_date')
?
?
values():
返回是字典(列表套字典),而不是模型實(shí)例對(duì)象;
>>> Blog.objects.filter(name__startswith='beatles')
>>> Blog.objects.filter(name__startswith='beatles').values()
>>> Blog.objects.values()
>>> Blog.objects.values('id','name')?? #可指定顯示某些字段
?
?
values_list():
返回列表套元組;
>>> Entry.objects.values_list('id')
>>> Entry.objects.values_list('id').order_by('id')
>>> Entry.objects.values_list('id',flat=True)?? #可指定顯示某些字段;flat扁平,若元組中僅1個(gè)元素用flat會(huì)將元組脫掉,結(jié)果為列表
>>> Entry.objects.values_list('id',flat=True).order_by('id')
?
?
defer()、only():
若模型包含一些含有大量數(shù)據(jù)的類型,通常模型會(huì)將數(shù)據(jù)庫(kù)取出的數(shù)據(jù)轉(zhuǎn)換為py對(duì)象,有時(shí)可不需要浪費(fèi)這樣的性能,用defer排隊(duì)、only僅轉(zhuǎn)換指定的(將指定的字段轉(zhuǎn)為可用屬性方式訪問);
>>> Entry.objects.defer('headline')
>>> Entry.objects.only('headline')
?
?
using():
使用哪個(gè)數(shù)據(jù)庫(kù);
在一主多從情況下,將查詢指定到從庫(kù)上,在settings.py中配;
DATABASES = {
??? 'default': {
??????? 'ENGINE': 'django.db.backends.sqlite3',
??????? 'NAME': os.path.join(BASE_DIR, 'db0.sqlite3'),
??? },
??? 'backup': {...},
}
>>> Entry.objects.all()
>>> Entry.objects.using('default')?? #Entry.objects.using('backup')
?
?
select_for_update():
返回一個(gè)queryset,會(huì)鎖定相關(guān)行直到事務(wù)結(jié)束,在支持的數(shù)據(jù)庫(kù)上產(chǎn)生一個(gè)select ... for update語句;
>>> Entry.objects.select_for_update().filter(authors=Author.objects.get(id=1))
?
?
raw():
執(zhí)行原始sql;
>>> for s in Blog.objects.raw('select * from blog_blog'):
...???? print(s)
...
beatles blog
test2
?
?
get_or_create()、update_or_create():
能查到,返回;查不到,創(chuàng)建;
obj, created = Person.objects.get_or_create(
???????? first_name='John',
???????? last_name='Lennon',
???????? defaults={'birthday':date(2019,1,8)},
)
等價(jià)于
try:
???????? obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
???????? obj = Person(first_name='John',last_name='Lennon',birthday=date(2019,1,8))
???????? obj.save()
?
?
bulk_create():
批量創(chuàng)建;
>>> Blog.objects.bulk_create([Blog(name='test3',tagline='test3'),Blog(name='test4',tagline='test4')])
[
?
?
in_bulk():
將主鍵封裝成列表,返回指定主鍵的記錄;
>>> Blog.objects.in_bulk([3,4])
{3:
>>> Blog.objects.in_bulk([1,3])
{1:
?
?
latest()、earliest、first()、last():
>>> Entry.objects.latest('pub_date')
>>> Entry.objects.earliest('pub_date')
?
?
get_lastest_by()經(jīng)常用,在Meta中指定;
?
?
事務(wù)是在view中實(shí)現(xiàn),在函數(shù)執(zhí)行完后才統(tǒng)一commit,默認(rèn)是autocommit;
例:
from django.db import transaction
?
@transaction.atomic
def my_view(request):
??? do_stuff()
???
@transaction.atomic
def viewfunc(request):
??? do_stuff()
?
?
?
?
1、添加額外管理器,是為類增加“表級(jí)”功能的首選方式,可返回你想要的任何數(shù)據(jù),而不是返回一個(gè)查詢集;
如果要添加行級(jí)功能,如只對(duì)某個(gè)模型的實(shí)例起作用,應(yīng)使用模型方法,而不是管理器方法;
?
?
?
2、添加自定義管理器:
from django.utils.translation import ugettext as _
?
class AuthorManager(models.Manager):
??? def get_queryset(self):
??????? return super(AuthorManager, self).get_queryset().filter(role='A')
?
class EditorManager(models.Model):
??? def get_queryset(self):
??????? return super(EditorManager, self).get_queryset().filter(role='E')
?
class Person(models.Model):
??? first_name = models.CharField(max_length=50)
??? last_name = models.CharField(max_length=50)
??? role = models.CharField(max_length=1, choices=(('A', _('Author'), ('E',_('Editor')))))
??? people = models.Manager()
??? authors = AuthorManager()
??? editors = EditorManager()
?
?
?
?
?
?