溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

98django_model2

發(fā)布時(shí)間:2020-08-02 14:02:11 來源:網(wǎng)絡(luò) 閱讀:230 作者:chaijowin 欄目:編程語言

?

目錄

queries... 1

exclude()... 3

關(guān)聯(lián)對(duì)象查詢:... 3

反向查詢對(duì)<field-name>_set改名:... 4

復(fù)雜查詢:... 4

保存ForeignKeyManyToMany字段:... 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

?

?

?

queries

?

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è)管理器的名字是<field-name>_set<field-name>是源模型的小寫名稱,該管理器返回的查詢集可用get、filterexclude再次操作;如CourseLesson,Lesson中的course = models.ForeignKey(Course, verbose_name='課程'),在Course中可定義方法def get_lesson(self): return self.lesson_set.all()

?

?

例:

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)

<class 'django.db.models.query.QuerySet'>

>>> user.groups.set(groups)?? #將用戶為'jowin'加入多個(gè)組里

>>> user.groups.all()

<QuerySet [<Group: magedu1>, <Group: magedu2>]>

>>> group = Group.objects.get(id=1)

>>> group.user_set.all()?? #反查會(huì)加上_set

<QuerySet [<User: jowin>]>

?

?

例,多對(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

?

例:

?

?

exclude()

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')

<QuerySet [<Author: mage>]>

?

?

關(guān)聯(lián)對(duì)象查詢:

>>> 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ì)象

<Blog: beatles blog>

>>> e.authors.set(Author.objects.all())

>>> e.authors.all()

<QuerySet [<Author: jowin>, <Author: mage>, <Author: jowin>]>

?

>>> b = Blog.objects.get(id=1)

>>> b.entry_set.all()?? #一對(duì)多,反向查詢,模型中有fk,該fk所指的模型實(shí)例可通過一個(gè)管理器返回前一個(gè)模型的所有實(shí)例,默認(rèn)這個(gè)管理器的名字是<field-name>_set,<field-name>是源模型的小寫名稱,該管理器返回的查詢集可用get、filterexclude再次操作

<QuerySet [<Entry: test>]>

>>> b.entry_set.filter(headline__contains='test')

<QuerySet [<Entry: test>]>

>>> b.entry_set.count()

1

?

?

反向查詢對(duì)<field-name>_set改名:

class Entry(models.Model):

???????? blog = models.ForeignKey(Blog, related_name='entries')

使用時(shí)用entries_set;

?

?

復(fù)雜查詢:

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、filterexclude中可混合使用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'))

<QuerySet [<Author: jowin>, <Author: mage>, <Author: jowin>]>

?

?

保存ForeignKeyManyToMany字段:

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

<Blog: test2>

>>> 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)建fkvalue

<Author: mage3>

?

?

QuerySet鏈?zhǔn)竭^濾:

Entry.objects.filter(headline__startswith='what').exclude(pub_date__gte=datetime.date.today()).filter(pub_date__gte=datetime(2019,1,8))

?

?

lookup,高級(jí)條件過濾:

使用<field-name>__lookup,使用雙下劃線來查詢;

gtgte、lt、lte

contains?? #包含

exact?? #精確匹配,默認(rèn)

startswith?? #開始于

endswith?? #結(jié)束于

regex??? #RE

icontainsiexact、istartswithiendwith、iregex?? #忽略大小寫

in?? #在列表中

range?? #范圍之內(nèi)

date、year、month、day?? #時(shí)間日期類型

?

>>> Entry.objects.filter(pub_date__gt='2018-12-31')

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Blog.objects.get(name__iexact='beatles blog')

<Blog: beatles blog>

>>> Blog.objects.filter(pk__in=[0,2,4])

<QuerySet [<Blog: test2>]>

>>> Entry.objects.filter(pub_date__range=(datetime.date(2018,12,31),datetime.date(2019,1,9)))

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Entry.objects.get(body_text__regex=r'^test2')?? #

<Entry: test2>

?

?

跨關(guān)聯(lián)關(guān)系查詢:

>>> Entry.objects.filter(blog__name='beatles blog')

<QuerySet [<Entry: test>]>

>>> Blog.objects.filter(entry__headline__contains='test')?? #反向

<QuerySet [<Blog: beatles blog>, <Blog: test2>]>

>>> Blog.objects.filter(entry__authors__name__isnull=True)?? #多層

<QuerySet []>

>>> Blog.objects.filter(entry__authors__isnull=False,entry__authors__name__isnull=True)?? #多個(gè)過濾條件

<QuerySet []>

?

>>> from django.db.models import F?? #模型字段查詢F,通常是將模型字段與常量比較,或比較2個(gè)字段值

>>> Entry.objects.filter(n_pingbacks__gt=F('n_comments'))?? #點(diǎn)贊數(shù)大于評(píng)論數(shù)

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Entry.objects.filter(rating__gt=F('n_comments') + F('n_pingbacks'))

<QuerySet [<Entry: test>]>

?

?

限制返回個(gè)數(shù):

>>> Entry.objects.all()[:3]?? #limit 5

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Entry.objects.all()[1:2]?? #offset 1 limit 1

<QuerySet [<Entry: test2>]>

?

?

查詢對(duì)象比較,用==,在后臺(tái)比較的是2個(gè)模型主鍵的值:

some_entry == other_entry?? #some_entry.id == other_entry.id

?

?

不常用查詢API

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

<QuerySet [<Blog: beatles blog>, <Blog: test2>]>

>>> 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()

<QuerySet [<Author: jowin>, <Author: mage>, <Author: jowin>, <Author: mage2>, <Author: jowin2>, <Author: mage3>]>

>>> Entry.objects.order_by('blog')

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Entry.objects.order_by('pub_date')

<QuerySet [<Entry: test>, <Entry: test2>]>

?

?

values()

返回是字典(列表套字典),而不是模型實(shí)例對(duì)象;

>>> Blog.objects.filter(name__startswith='beatles')

<QuerySet [<Blog: beatles blog>]>

>>> Blog.objects.filter(name__startswith='beatles').values()

<QuerySet [{'name': 'beatles blog', 'id': 1, 'tagline': 'all the latest beatles news'}]>

>>> Blog.objects.values()

<QuerySet [{'name': 'beatles blog', 'id': 1, 'tagline': 'all the latest beatles news'}, {'name': 'test2', 'id': 2, 'tagline': 'test2'}]>

>>> Blog.objects.values('id','name')?? #可指定顯示某些字段

<QuerySet [{'name': 'beatles blog', 'id': 1}, {'name': 'test2', 'id': 2}]>

?

?

values_list()

返回列表套元組;

>>> Entry.objects.values_list('id')

<QuerySet [(1,), (2,)]>

>>> Entry.objects.values_list('id').order_by('id')

<QuerySet [(1,), (2,)]>

>>> Entry.objects.values_list('id',flat=True)?? #可指定顯示某些字段;flat扁平,若元組中僅1個(gè)元素用flat會(huì)將元組脫掉,結(jié)果為列表

<QuerySet [1, 2]>

>>> Entry.objects.values_list('id',flat=True).order_by('id')

<QuerySet [1, 2]>

?

?

defer()、only()

若模型包含一些含有大量數(shù)據(jù)的類型,通常模型會(huì)將數(shù)據(jù)庫取出的數(shù)據(jù)轉(zhuǎn)換為py對(duì)象,有時(shí)可不需要浪費(fèi)這樣的性能,用defer排隊(duì)、only僅轉(zhuǎn)換指定的(將指定的字段轉(zhuǎn)為可用屬性方式訪問);

>>> Entry.objects.defer('headline')

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Entry.objects.only('headline')

<QuerySet [<Entry: test>, <Entry: test2>]>

?

?

using()

使用哪個(gè)數(shù)據(jù)庫;

在一主多從情況下,將查詢指定到從庫上,在settings.py中配;

DATABASES = {

??? 'default': {

??????? 'ENGINE': 'django.db.backends.sqlite3',

??????? 'NAME': os.path.join(BASE_DIR, 'db0.sqlite3'),

??? },

??? 'backup': {...},

}

>>> Entry.objects.all()

<QuerySet [<Entry: test>, <Entry: test2>]>

>>> Entry.objects.using('default')?? #Entry.objects.using('backup')

<QuerySet [<Entry: test>, <Entry: test2>]>

?

?

select_for_update()

返回一個(gè)queryset,會(huì)鎖定相關(guān)行直到事務(wù)結(jié)束,在支持的數(shù)據(jù)庫上產(chǎn)生一個(gè)select ... for update語句;

>>> Entry.objects.select_for_update().filter(authors=Author.objects.get(id=1))

<QuerySet [<Entry: test>]>

?

?

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')])

[<Blog: test3>, <Blog: test4>]

?

?

in_bulk()

將主鍵封裝成列表,返回指定主鍵的記錄;

>>> Blog.objects.in_bulk([3,4])

{3: <Blog: test3>, 4: <Blog: test4>}

>>> Blog.objects.in_bulk([1,3])

{1: <Blog: beatles blog>, 3: <Blog: test3>}

?

?

latest()、earliestfirst()、last()

>>> Entry.objects.latest('pub_date')

<Entry: test>

>>> Entry.objects.earliest('pub_date')

<Entry: test>

?

?

get_lastest_by()經(jīng)常用,在Meta中指定;

?

?

事務(wù):

事務(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()

?

?

?

?

?

?


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI