有一個在這個帖子一些有用的信息,所以我不認爲它應該被刪除,但有一個非常非常簡單的解決方案
我快速瀏覽了django-tagging的源代碼。看起來他們使用ContentType框架和泛型關係來實現它。
正因爲如此,你應該能夠創建自己的位置類generic reverse relation獲得輕鬆前往TaggedItem對象爲給定的位置,如果你還沒有這樣做:
from django.contrib.contenttypes import generic
from tagging.models import TaggedItem
class Location(models.Model):
...
tagged_items = generic.GenericRelation(TaggedItem,
object_id_field="object_id",
content_type_field="content_type")
...
澄清
我原來的答覆建議要做到這一點:
untagged_locs = Location.objects.filter(tagged_items__isnull=True)
雖然該W烏爾德工作了「正常參與」,這其實並不在這裏,因爲內容類型框架拋出的content_type_id
額外的檢查,到SQL爲isnull
工作:
SELECT [snip] FROM `sotest_location`
LEFT OUTER JOIN `tagging_taggeditem`
ON (`sotest_location`.`id` = `tagging_taggeditem`.`object_id`)
WHERE (`tagging_taggeditem`.`id` IS NULL
AND `tagging_taggeditem`.`content_type_id` = 4)
您可以通過反轉像劈周圍這個:
untagged_locs = Location.objects.exclude(tagged_items__isnull=False)
但是,這不太對勁。
我也提出過這個,但是有人指出annotations don't work as expected與內容類型框架有關。
from django.db.models import Count
untagged_locs = Location.objects.annotate(
num_tags=Count('tagged_items')).filter(num_tags=0)
上面的代碼對我的作品在我有限的測試案例,但它可能是越野車,如果你有你的模型等「加標籤」的對象。原因是它不檢查the ticket中概述的content_type_id
。它生成以下SQL:
SELECT [snip], COUNT(`tagging_taggeditem`.`id`) AS `num_tags`
FROM `sotest_location`
LEFT OUTER JOIN `tagging_taggeditem`
ON (`sotest_location`.`id` = `tagging_taggeditem`.`object_id`)
GROUP BY `sotest_location`.`id` HAVING COUNT(`tagging_taggeditem`.`id`) = 0
ORDER BY NULL
如果Location
是你唯一的加標籤的對象,那麼上面會工作。
建議解決方法
短期獲得註釋的工作機制的,這裏就是我會在此期間做到:
untagged_locs_e = Location.objects.extra(
where=["""NOT EXISTS(SELECT 1 FROM tagging_taggeditem ti
INNER JOIN django_content_type ct ON ti.content_type_id = ct.id
WHERE ct.model = 'location'
AND ti.object_id = myapp_location.id)"""]
)
這增加了額外的WHERE子句中的SQL:
SELECT [snip] FROM `myapp_location`
WHERE NOT EXISTS(SELECT 1 FROM tagging_taggeditem ti
INNER JOIN django_content_type ct ON ti.content_type_id = ct.id
WHERE ct.model = 'location'
AND ti.object_id = myapp_location.id)
它加入到django_content_type
表中以確保您正在查看適當的 您的模型的內容類型在您有多個標籤模型類型的情況下。
更改myapp_location.id
以匹配您的表名稱。可能有一種方法可以避免對錶名進行硬編碼,但是如果對你很重要,你可以弄清楚。
如果您不使用MySQL,請相應地進行調整。
'object \ _id \ _field'和'content \ _type \ _field'參數在這裏是沒有意義的,因爲它們完全默認正在傳遞的內容,但是我覺得包括它們會有助於展示API。 – 2009-11-30 19:20:31
感謝您提供一個很好的答案!然而,我可能做錯了什麼,但我無法讓它工作。我可以得到'Location.objects.filter(tagged_items__isnull = False)'給我一組帶標籤的項目,但是'Location.objects.filter(tagged_items__isnull = True)'只是給了我一個空的查詢集合。 – lemonad 2009-11-30 22:55:25
另外,註釋真的可以正常使用泛型關係嗎?下面的票據表明它沒有:http://code.djangoproject.com/ticket/10461 – lemonad 2009-11-30 23:03:48