이 게시물에 몇 가지 좋은 정보가있다, 그래서 그것을 삭제해야한다고 생각하지 않지만, 훨씬, 훨씬 더 간단한 해결책이있다
장고 태그에 대한 소스 코드를 빠르게 살펴 보았습니다. 그들은 ContentType 프레임 워크와 일반적인 관계를 사용하여 그것을 제거한 것처럼 보입니다.
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")
...
: 아직 수행하지 않은 경우이 때문에
, 당신은, 주어진 위치의 TaggedItem 객체에 쉽게 접근 할 수 있도록 위치 클래스에 generic reverse relation을 만들 수있을 것입니다 이 w 비록
untagged_locs = Location.objects.filter(tagged_items__isnull=True)
: 내 원래의 대답은이 일을 제안
해명 작동 울드 상기 콘텐츠 형식 프레임 워크는 isnull
에 대한 SQL에 content_type_id
에 대한 추가 검사가 발생하기 때문에,이 실제로 여기에 작동하지 않습니다 '에 가입 정상'
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)
위의 코드
내 제한된 테스트 케이스에 나를 위해 작동하지만이 모델의 다른 'taggable'객체가있는 경우는 버그가 될 수 있습니다. 그 이유는
the ticket에 설명 된대로
content_type_id
을 확인하지 않기 때문입니다.
Location
이 유일한 taggable 목적은
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
경우, 위의 작동합니다 : 그것은 다음과 같은 SQL을 생성합니다.
제안 된 해결 방법, 여기에 내가 그동안 어떻게 할 것인지 작동하도록 주석 메커니즘을 얻기의 짧은이다
:
이
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)"""]
)
이 추가로 추가 곳 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를 표시하는 것이 도움이된다는 생각이 들었습니다. –
멋진 답변을 제공해 주셔서 감사합니다! 그러나, 나는 틀린 일을하고 있을지도 모르지만 나는 일할 수 없습니다. tagged items의 집합을 제공하기 위해'Location.objects.filter (tagged_items__isnull = False) '를 얻을 수는 있지만'Location.objects.filter (tagged_items__isnull = True)'는 단지 빈 쿼리를 제공한다. – lemonad
또한 주석은 제네릭 관계에서 올바르게 작동합니까? 다음 티켓은 그렇지 않다는 것을 나타냅니다. http://code.djangoproject.com/ticket/10461 – lemonad