django queryset tutorial 2

dooh kim·2020년 9월 9일
0

queryset-tutorial

목록 보기
2/5

Spanning multi-valued relationships

When you are filtering an object based on a ManyToManyField or a reverse ForeignKey, there are two different sorts of filter you may be interested in. Consider the Blog/Entry relationship (Blog to Entry is a one-to-many relation). We might be interested in finding blogs that have an entry which has both “Lennon” in the headline and was published in 2008. Or we might want to find blogs that have an entry with “Lennon” in the headline as well as an entry that was published in 2008. Since there are multiple entries associated with a single Blog, both of these queries are possible and make sense in some situations.

The same type of situation arises with a ManyToManyField. For example, if an Entry has a ManyToManyField called tags, we might want to find entries linked to tags called “music” and “bands” or we might want an entry that contains a tag with a name of “music” and a status of “public”.

To handle both of these situations, Django has a consistent way of processing filter() calls. Everything inside a single filter() call is applied simultaneously to filter out items matching all those requirements. Successive filter() calls further restrict the set of objects, but for multi-valued relations, they apply to any object linked to the primary model, not necessarily those objects that were selected by an earlier filter() call.

That may sound a bit confusing, so hopefully an example will clarify. To select all blogs that contain entries with both “Lennon” in the headline and that were published in 2008 (the same entry satisfying both conditions), we would write:

Blog / Entry

Blog를 찾는다
1. Blog에는 여러 Entry들이 속해있을 텐데, 그 속한 Entry들 중 
headline에 "Lennon"을 포함하며, 2008년에 발행된 Entry가 있는 경우
인 Blog(하나의 Entry가 2개의 조건을 동시에 만족)

2. Blog에는 여러 Entry들이 속해있을 텐데 , 그 속한 Entry들 중 
headline에 "Lennon"을 포함한 Entry도 있으며 2008년에발행된 
Entry도 있는 경우( 여러개의 Entry가 각각의 조건 하나씩만 만족하면 됨)


Blog1
Blog-Entry1
- Headline : Lennon
- Publish : 2008

Blog2
Blog2 - Entry2
- Headline: Lennon
- Publish : 2020


Blog2 - Entry3
- Headline : WPS
- Publish : 2008

Blog3
Blog3 - Entry4
- Headline : Lennon
- Publish: 2020

example


b1 = Blog.objects.create(name='Blog1')
b2 = Blog.objects.create(name='Blog2')
b3 = Blog.objects.create(name='Blog3')
b4 = Blog.objects.create(name='Blog4')


from datetime import date
e1 = Entry.objects.create(
    blog=b1,
    headline='Lennon',
    pub_date=date(2008, 3, 3),
)
e2 = Entry.objects.create(
    blog=b2,
    headline='Lennon',
    pub_date=date(2020, 3, 3),
)
e3 = Entry.objects.create(
    blog=b2,
    headline='WPS',
    pub_date=date(2008, 3, 3),
)
e4 = Entry.objects.create(
    blog=b3,
    headline='Lennon',
    pub_date=date(2020, 6, 6),
)
e5 = Entry.objects.create(
    blog=b4,
    headline='WPS',
    pub_date=date(2008, 6, 6),
)


# 두개의 조건을 모두 만족 시키는 경우 and 개념
Blog.objects.filter(entry__headline__contains='Lennon',
entry__pub_date__year=2008)

<QuerySet [<Blog: Blog1>]>

# 두개의 조건 중 하나를 만족 시키는 결과들의 교집합
Blog.objects.filter(entry__headline__contains='Lennon').filter(
entry__pub_date__year=2008)

<QuerySet [<Blog: Blog1>, <Blog: Blog2>]>


# filter와 같은 개념과 다르게 둘 중 하나라도 만족시킨 결과들의 합집합
Blog.objects.exclude(
    entry__headline__contains='Lennon',
    entry__pub_date__year=2008,
)

<QuerySet [<Blog: Blog3>, <Blog: Blog4>]>
profile
testify to the light

0개의 댓글