2016-09-19 3 views
0

folgende Modelle zu haben:Filtertags von django-taggit in Djangos Queryset

class Post(models.Model): 
    title = models.CharField(max_length=250) 
    tags = TaggableManager() 

und die Daten sind:

**post.title**       **post.tags** 
Django By Example      python,django,web 
Who was Django Reinhardt    python,django, 
Test-Driven Development with Python  python,web 
Python for Data Analysis    python,data   
Learning Python       python 
Programming Python      python 
Automate the Boring Stuff with Python python 

Ich versuche unter

>>> alist=Post.objects.filter(tags__name__in=["data","python"]) 
>>> for i in alist.annotate(sam_tags=Count('tags')): 
...  print("\n---",i) 
...  print("tags of it : ",i.tags.all()) 
...  print("value of sam_tags : ",i.sam_tags) 
... 

--- Django By Example 
tags of it : [<Tag: django>, <Tag: python>, <Tag: web>] 
value of sam_tags : 1 

--- Who was Django Reinhardt 
tags of it : [<Tag: django>, <Tag: python>] 
value of sam_tags : 1 

--- Automate the Boring Stuff with Python 
tags of it : [<Tag: python>] 
value of sam_tags : 1 

--- Test-Driven Development with Python 
tags of it : [<Tag: python>, <Tag: web>] 
value of sam_tags : 1 

--- Learning Python 
tags of it : [<Tag: python>] 
value of sam_tags : 1 

--- Python for Data Analysis 
tags of it : [<Tag: data>, <Tag: python>] 
value of sam_tags : 2 

--- Programming Python 
tags of it : [<Tag: python>] 
value of sam_tags : 1 
>>> 

zu codieren, warum der Wert von slist [0] .sam_tags (Post: Django By Example) ist gleich 1?

Ich denke, das Post-Objekt von (Post: Django By Example) hat drei Tags [Python, Django und Web] nach dem Lesen der Django-Dokumentation.

https://docs.djangoproject.com/en/1.10/ref/models/querysets/#count

es, dass Count (expression) die Anzahl der Objekte zurückgibt, die durch den Ausdruck bereitgestellt in Beziehung stehen. so dass der Code

>>>alist[0].tags.all() 
[<Tag: django>, <Tag: python>, <Tag: web>] 

zeigt, dass es drei Tags in alist [0] .tags,

>>> slist=alist.annotate(sam_tags=Count('tags')) 
>>> slist[0].tags.all() 
[<Tag: django>, <Tag: python>, <Tag: web>] 
>>> slist[0].sam_tags 
1 

aber hier bekomme ich den Wert 1,
warum?

Ich verstehe, dass Django zählt nur die "Python" und "Daten" Tags, die ich in meiner Filterklausel enthalten - andere Tags werden nicht gezählt.

Die Ausgabe von "slist [0] .tags.all()" zeigt, dass Slist [0] drei Tags hat, die mit sich selbst zusammenhängen. Da die Dokumentation von django besagt, dass Count (Ausdruck) die Anzahl der Objekte zurückgibt, die durch den angegebenen Ausdruck in Beziehung stehen, sollte slist [0] .sam_tags laut Dokumentation 3 sein, aber django-taggit macht slist [0] .sam_tags zu be 1.

Also was ich wirklich wissen möchte ist, wie Django-Taggit Count (Ausdruck) in der Filterklausel berechnet nur die Anzahl der Tags in der Filterbedingung.

Antwort

1

Django zählt nur die Tags python und data, die Sie in Ihre Filterklausel aufgenommen haben - andere Tags werden nicht gezählt. (Beachten Sie, dass das einzige Beispiel mit sam_tags von 2 das ist, das sowohl data als auch python markiert.) Dies ist wahrscheinlich ein unerwartetes Verhalten, macht aber Sinn, wenn Sie berücksichtigen, wie das zugrunde liegende SQL ausgeführt wird. Sehen Sie dieses Beispiel aus einem ähnlichen Schema zu verkaufen:

>>> a = Article.objects.filter(tags__slug__in=['python']).annotate(num_tags=Count('tags'))[0] 
>>> a.num_tags 
1 
>>> a.tags.count() 
2 

Wenn ich die Filterklausel auf somethign andere als Tags zu filtern ändern, verhält es sich wie erwartet:

>>> Article.objects.filter(pk=a.pk).annotate(num_tags=Count('tags'))[0].num_tags 
2 
>>> Article.objects.filter(pk=a.pk).annotate(num_tags=Count('tags'))[0].tags.count() 
2 
+0

Ich verstehe, dass Django zählt nur die "python" und "data" -Tags, die ich in meine Filterklausel aufgenommen habe - andere Tags werden nicht gezählt, also bearbeite ich meine Frage, um meine Zweifel zu enthüllen. – polar9527