2015-02-04 4 views
1

Есть ли способ «Python/Django» для запроса/фильтрации объектов с помощью общего внешнего ключа? Я пытаюсь получить все объекты FullCitation для определенного программного обеспечения, где is_primary - True.Фильтр Generic Foreign Key

Я знаю, что я не могу это сделать, но я хочу сделать что-то вроде этого:

ct_supported = ContentType.objects.get(app_label="supportedprogram", model="software") 
primary_citations = FullCitation.objects.filter(content_type__name=ct_supported, object_id__in='', is_primary=True) 

models.py

class FullCitation(models.Model) 
    # the software to which this citation belongs 
    # either a supported software program or a non-supported software program 

    limit = models.Q(app_label = 'myprograms', model = 'supportedprogram') | models.Q(app_label = 'myprograms', model = 'nonsupportedprogram') 
    content_type = models.ForeignKey(ContentType), limit_choices_to = limit,) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

    is_primary = models.BooleanField(help_text="Is this the Primary Citation for the software program?") 

class NonSupportedProgram(models.Model): 
    title = models.CharField(max_length=256, blank = True) 
    full_citation = generic.GenericRelation('FullCitation') 

class SupportedProgram(models.Model): 
    title = models.CharField(max_length=256, blank = True) 
    full_citation = generic.GenericRelation('FullCitation') 
    # and a bunch of other fields..... 

views.py # Моя текущая попытка

primary_citations = [] 
sw_citations = sw.full_citations.all() 
    for x in sw_citations: 
     if x.is_primary: 
      primary_citations.append(x) 
+0

Quickfix: используйте список comprehesion [ cit для cit в sw.full_citations.all() if cit.is_primary] – Alvaro

+0

Спасибо, @Alvaro! Это определенно помогает. Просто интересно, есть ли способ фильтрации на самом объекте FullCitation, который был бы более Django-ish ... если нет, я обязательно использую понимание списка! – steph

+0

Вы также можете использовать генераторное понимание '(x for x in y)' для задержки запроса базы данных и выполнять его только при необходимости. –

ответ

4

Понимание должно быть последним средством фильтрации QuerySets. Намного лучше позволить им оставаться как QuerySets до тех пор, пока вы можете. Я думаю, что это то, что вы ищете:

ct_supported = ContentType.objects.get_for_model(SupportedProgram)) 
primary_citations = FullCitation.objects.filter(content_type=ct_supported, is_primary=True) 

Обновлено: Если вы хотите, чтобы фильтр для конкретного экземпляра SupportedProgram, сделайте следующее:

my_supported = SupportedProgram.objects.get(id=instance_id_goes_here) 
ct_supported = ContentType.objects.get_for_model(SupportedProgram)) 
primary_citations = FullCitation.objects.filter(content_object=my_supported, content_type=ct_supported, is_primary=True) 
+0

это почти все, но не совсем (определенно в духе того, что я ищу!). Мне нужен еще один «уровень» фильтрации. Я хочу фильтровать не только на моделях SupportedProgram, но и на конкретном экземпляре поддерживаемой программы. Итак, я хочу, чтобы все FullCitations, где SupportedProgram, в частности, «Program1», а затем, из тех FullCitations, я хочу только те, где is_primary = True .... – steph

+0

@steph Обновлено для фильтрации для конкретного экземпляра SupportedProgram. – dylrei

+0

Большое вам спасибо! @dylrei – steph