الحصول على مجموعة طلبات البحث من الكائنات من خلال نموذج وسيط

StackOverflow https://stackoverflow.com/questions/1417828

سؤال

وأريد الحصول على كافة الكائنات GEOM التي ترتبط إلى content_object معينة (انظر وظيفة أحاول بناء في الجزء السفلي، 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 سوف تستخدم بسيط جملة WHERE على التسجيل الذي يجب القيام به على أي حال. الفرق في الأداء مهم:

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