포함을 사용하여 Django 필터 다 대다


87

다 대다 관계를 통해 여러 개체를 필터링하려고합니다. 때문에 trigger_roles필드가 여러 항목이 포함될 수 있습니다 나는 시도 contains필터를. 그러나 그것이 문자열과 함께 사용되도록 설계 되었기 때문에 나는이 관계를 어떻게 필터링 해야하는지 거의 무력합니다 ( values_list()atm을 무시할 수 있습니다 .).

이 기능은 사용자 프로필에 연결됩니다.

def getVisiblePackages(self):
    visiblePackages = {}   
    for product in self.products.all():
        moduleDict = {}
        for module in product.module_set.all():
            pkgList = []
            involvedStatus = module.workflow_set.filter(trigger_roles__contains=self.role.id,allowed=True).values_list('current_state', flat=True)

내 워크 플로 모델은 다음과 같습니다 (단순화 됨).

class Workflow(models.Model):
    module = models.ForeignKey(Module)
    current_state = models.ForeignKey(Status)
    next_state = models.ForeignKey(Status)
    allowed = models.BooleanField(default=False)
    involved_roles = models.ManyToManyField(Role, blank=True, null=True)
    trigger_roles = models.ManyToManyField(Role, blank=True, null=True)

해결책은 조용하지만 간단 할 수 있지만 내 뇌는 말하지 않습니다.

당신의 도움을 주셔서 감사합니다.

답변:


109

다음과 같은 것을 시도해 보셨습니까?

module.workflow_set.filter(trigger_roles__in=[self.role], allowed=True)

또는 self.role.idpks 목록이 아닌 경우 :

module.workflow_set.filter(trigger_roles__id__exact=self.role.id, allowed=True)

1
작동하지 않는 것 같습니다. self.role.id는 단지 하나의 int이고 trigger_roles는 그것들의 목록이기 때문에, contains와 같은 반전이 필요하지만, contains는 문자열 전용입니다.
Grave_Jumper 2010

8
두 번째 예는 해야 작동합니다. 의 값 self.role.id이 트리거 역할 중 하나이면 해당 필터는 트리거 역할 중 하나가의 값인 모든 워크 플로를 가져와야합니다 self.role.id. 기본적으로 이것은 "포함"함수와 똑같이 작동합니다. 우리 모두가 뭔가를 놓치고 있지 않는 한.
Jordan Reiter

@Jordan Reiter : "contains"는 OP가 원하는 것이 아닌 "like"로 SQL에서 변환되며, 그가 이미 지적했다고 생각합니다. 반면에 "exact"는 "="또는 "is"로 변환됩니다. 여기에 아이디어.
mouad

@Grave_Jumper은 : 여기 봐 (받아 djangoproject.com/documentation/models/many_to_many : 내 대답이없는 경우,이 당신을 도울 수 있기를 바랍니다, ManytoMany 필드를 작업 할 때 몇 가지 예를 찾을 수 있습니다)
mouad

1
aww .. 죄송합니다 두 번째 솔루션이 조용히 잘 작동합니다. :) 내쪽에 약간의 구성이 잘못되었습니다. 감사합니다 사람이 내 하루 ;-) 저장
Grave_Jumper

18

이를 달성하는 가장 간단한 방법은 .NET Framework에서 전체 인스턴스 (ID 대신)에 대한 동등성을 확인하는 것 ManyToManyField입니다. 인스턴스가 다 대다 관계 내에 있는지 확인합니다. 예:

module.workflow_set.filter(trigger_roles=self.role, allowed=True)

6

나는 이것이 오래된 질문이라는 것을 알고 있지만 OP가 그가 찾고 있던 대답을 얻지 못한 것 같습니다. 당신은 당신이 비교할 ManyToManyFields 두 세트가있는 경우, 트릭이 사용하는 것입니다 __in, 연산자를하지 contains. 예를 들어 필드에 ManyToMany가 "Group"인 "Event"모델이 있고 eventgroups사용자 모델 (분명히)이 Group에 연결된 경우 다음과 같이 쿼리 할 수 ​​있습니다.

Event.objects.filter(eventgroups__in=u.groups.all())


4

첫 번째 예에서는 특이점이 거의 맞습니다. 목록인지 확인하기 만하면됩니다. 두 번째 예는 확인하는 trigger_roles__id__exact것이 더 나은 솔루션입니다.

module.workflow_set.filter(trigger_roles__in=[self.role.id],allowed=True)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.