2010-04-27 3 views
2

3 개의 모델이 있으며 TaggedObject에는 ObjectTagBridge가있는 GenericRelation이 있습니다. ObjectTagBridge에는 태그 모델에 대한 ForeignKey가 있습니다. Many2Many/Generic 관계를 Q와 올바르게 필터링하는 방법은 무엇입니까?

class TaggedObject(models.Model): 
    """ 
     class that represent a tagged object 
    """ 
    tags = generic.GenericRelation('ObjectTagBridge', 
            blank=True, null=True) 

class ObjectTagBridge(models.Model): 
    """ 
     Help to connect a generic object to a Tag. 
    """ 
    # pylint: disable-msg=W0232,R0903 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
    tag = models.ForeignKey('Tag') 

class Tag(models.Model): 
    ... 

내가 객체에 태그를 부착하고

, 나는 새로운 ObjectTagBridge을 만들고 내가 첨부 할 태그에의 외래 키 태그를 설정하고있다. 그게 잘 작동하고, 나는 아주 쉽게 내 개체에 첨부 된 모든 태그를 얻을 수 있습니다. 하지만 TAG1과 TAG2있는 모든 개체 (필터)를 취득 할 때 나는 이런 식으로 뭔가를 시도 :

query = Q(tags__tag=Tag1) & Q(tags__tag=Tag2) 
object_list = TaggedObjects.filter(query) 

있지만이 태그로 한 ObjectTagBridge이 TaggedObjects을 찾고 있기 때문에 지금 내 object_list은 비어 첫 번째는 Tag1이고 두 번째는 Tag2입니다.

내 응용 프로그램은이 질문보다 더 복잡한 Q 쿼리가 될 것이므로이 Q 개체와 함께 솔루션이 필요하다고 생각합니다. 실제로 같은 이진 연결자의 모든 조합 : (...) and ((...) or not(...))

어떻게 올바르게 필터링 할 수 있습니까? 모든 대답은 환영합니다, 어쩌면 다른 방법이 있습니다.

당신의 도움을 위해 !!!

답변

1

찾고있는 결과가 Tag1과 Tag2가있는 TaggedObject 인 경우 ObjectTagBridge를 쿼리하는 대신 TaggedObject를 쿼리하는 것이 좋습니다. 쿼리가 다음과 같이 표시됩니다.

results = TaggedObject.objects.filter(objecttagbridge__tag = Tag1).filter(objecttagbridge__tag = Tag2) 

기본적으로 우리는 두 개의 필터를 수행하고 있습니다. Tag1과 Tag2를 모두 가진 객체 만 필터링 기준을 통과하고 결과 집합의 일부가됩니다.

+0

네, 맞습니다. 나는 Q 객체로 그렇게 할 수 있기를 바랬다. 이 경우 다른 TaggedObjects에 대해 동일한 필터를 사용할 수 있습니다. API를 다시 작성하고 그런 식으로 구현했습니다. 고마워 –

0

수동으로 Many-to-Many 테이블을 구현 한 다음 일반 관계로 결합하는 것처럼 보입니다. 더 좋은 방법은 장고 당신을위한 M2M을 처리 할 수 ​​있도록, 그리고 그냥 그렇게 같은 일반적인 관계를 표현이있을 수 있습니다 ...

class TaggedObject(models.Model): 
    """ 
     Help to connect a generic object to a Tag. 
    """ 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
    tags = models.ManyToManyField('Tag') 

class Tag(models.Model): 
    ... 

이것은 당신이 당신이하려고했던 일을하도록해야

objects = TaggedObject.objects.filter(
    Q(tags=Tag1) & Q(tags=Tag2) 
) 
+0

xx. 하지만 내 경우에는 여분의 테이블이 필요하므로 <-> 오브젝트 관계에 추가 정보를 첨부해야합니다. 이 접근법의 또 다른 장점은 TaggedObject에서 상속받은 여러 클래스를 만들 수 있고 태그의 뷰에서 Object가 태그 지정되는 데 차이가 없다는 것입니다. –

관련 문제