문제

특정 Content_Object와 관련된 모든 geOM 객체를 얻고 싶습니다 (하단에서 빌드하려는 함수 참조, get_geoms_for_obj ()

class Geom(models.Model):
    ...

class GeomRelation(models.Model):
    ''' For tagging many objects to a Geom object and vice-versa'''

    geom = models.ForeignKey(Geom)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

def get_geoms_for_object(obj):
    ''' takes an object and gets the geoms that are related

    '''
    ct = ContentType.objects.get_for_model(obj)
    id = obj.id
    grs = GeomRelation.objects.filter( content_type=ct, object_id=id )
    # how with django orm magic can I build the queryset instead of list
    # like below to get all of the Geom objects for a given content_object
    geoms = []
    for gr in grs:
        geoms.append(gr.geom)
    return set(geoms)
    # A set makes it so that I have no redundant entries but I want the
    # queryset ordering too .. need to make it a queryset for so many reasons...
도움이 되었습니까?

해결책

이,

return Geom.objects.filter(geomrelation__in=grs)

다른 팁

geom 클래스에 generic.genericrelation () 속성이있는 경우 표준 거꾸로 관계를 통해 객체를 얻을 수 있습니다.

class Geom(models.Model):
    ...
    geom_relations = generic.GenericRelation(GeomRelation)

이것은 파이썬 전용 속성으로 데이터베이스 변경이 필요하지 않습니다. 이제 geom_relations를 얻으려면 다음과 같습니다.

geom.geom_relations.all()

하나의 쿼리 세트 객체를 다른 쿼리 세트 객체를 다른 쿼터 인수로 전달하면 ORM은 중첩 된 선택 문을 사용합니다. 필터 조회에서 테이블 관계를 연결하는 것이 좋습니다. 그러면 ORM은 조인에 대한 간단한 위치 조항을 사용하여 어쨌든해야합니다. 성능의 차이는 중요합니다.

In [2]: from django.db import connection
In [3]: from app.models import *
In [4]: ct = ContentType.objects.get_for_model(Thing)
In [5]: grs = GeomRelation.objects.filter( content_type=ct, object_id=2 )
In [6]: 
In [7]: # slow method
In [8]: list(Geom.objects.filter(geomrelation__in=grs));
In [9]: connection.queries[-1]
Out[9]: 
{'sql': u'SELECT "app_geom"."id" FROM "app_geom" INNER JOIN "app_geomrelation" ON ("app_geom"."id" = "app_geomrelation"."geom_id") WHERE "app_geomrelation"."id" IN (SELECT U0."id" FROM "app_geomrelation" U0 WHERE (U0."content_type_id" = 10  AND U0."object_id" = 2 ))',
 'time': '0.140'}
In [10]: 
In [11]: # fast method
In [12]: list(Geom.objects.filter(geomrelation__content_type=ct,
   ....:                         geomrelation__object_id=2));
In [13]: connection.queries[-1]
Out[13]: 
{'sql': u'SELECT "app_geom"."id" FROM "app_geom" INNER JOIN "app_geomrelation" ON ("app_geom"."id" = "app_geomrelation"."geom_id") WHERE ("app_geomrelation"."object_id" = 2  AND "app_geomrelation"."content_type_id" = 10 )',
 'time': '0.001'}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top