문제

다음과 같은 모델이 있습니다.

class Thing(models.Model):
    property1 = models.IntegerField()
    property2 = models.IntegerField()
    property3 = models.IntegerField()

class Subthing(models.Model):
    subproperty = models.IntegerField()
    thing = modelsForeignkey(Thing)
    main = models.BooleanField()

각 필터가 { 'type': something, 'value': x} 형식 인 필터 목록을 전달하는 함수가 있습니다. 이 기능은 결과 세트와 모든 필터를 함께 반환해야합니다.

final_q = Q()
for filter in filters:
        q = None
        if filter['type'] =='thing-property1':
            q = Q(property1=filter['value'])
        elif filter['type'] =='thing-property2':
            q = Q(property2=filter['value'])
        elif filter['type'] =='thing-property2':
            q = Q(property3=filter['value'])
        if q:
            final_q = final_q & q
return Thing.objects.filter(final_q).distinct()

각 하위 위치에는 부울 속성이 '메인'이 있습니다. 모든 것은 main == true 인 곳에서 1과 단 1 개의 서브 모든 것을 가지고 있습니다.

이제 서브가있는 모든 것을 반환하는 필터를 추가해야합니다. main==True 그리고 subproperty==filter['value']

이 작업을 수행 할 수 있습니까? Q 내가 구성하는 객체? 다른 방법이 아니라면? 새 필터가 상당히 커질 수 있기 전에 얻는 쿼리 세트는 결과를 반복하지 않는 메소드를 원합니다.

도움이 되었습니까?

해결책

당신이 당신의 잠수함이 사물과의 관계에서 "관련_name"을 명시 적으로 주면 이해하기가 조금 더 쉽습니다.

class Subthing(models.Model):
    ...
    thing = models.ForeignKey(Thing, related_name='subthings')
    ...

이제 사용합니다 Django 가입 구문 Q 개체를 구축하려면 :

Q(subthings__main=True) & Q(subthings__subproperty=filter['value'])

리버스 관계에는 기본 이름 'subthing_set'이 있지만 'Subthings'와 같은 더 나은 이름을 제공하면 따라 가기가 더 쉽다는 것을 알 수 있습니다.

다른 팁

사용 (대신 final_q=Q() 처음에는)

final_q=Q(subthing_set__main=True)
sub_vals = map(lambda v: v['value'], filters)
if sub_vals:
    final_q = final_q & Q(subthing_set__subproperty__in=sub_vals)

원하는 것을 얻으려면 루프를 조정하여 Sub_Vals 목록을 작성하고 루프 후에 적용 할 수도 있습니다.

subthing_set은 관련 하위 트레이닝에 액세스하기 위해 관련 필드가 추가되어 자동으로 추가됩니다.

다른 관련 이름 (예 :

thing=models.ForeignKey(Thing,related_name='subthings')
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top