用于查找相关外键字段的Django Queryset

时间:2014-10-27 00:38:07

标签: django django-models django-forms

我正在尝试将相关字段查询到Catalog类,其中许多项与外键相关。我正在尝试:

article = forms.ModelChoiceField(queryset=Catalog.objects.select_related(
    'article_products'))

它似乎执行相同的查询:

queryset = Catalog.objects.all()

任何人都可以帮助引导我朝着正确的方向前进吗?这是我正在使用的模型。

class Catalog(models.Model):
    products = models.CharField(max_length=200)

    def __unicode__(self):
        return self.products

class Article(models.Model):
    catalog = models.ForeignKey(Catalog, related_name='article_products')
    title = models.CharField(max_length=200)
    abstract = models.TextField(max_length=1000, blank=True)
    full_text = models.TextField(blank=True)
    proquest_link = models.CharField(max_length=200, blank=True, null=True)
    ebsco_link = models.CharField(max_length=200, blank=True, null=True)

    def __unicode__(self):
        return self.title

我的目标是让表单选择字段包含与目录相关的所有文章。它目前只显示目录的名称。

1 个答案:

答案 0 :(得分:1)

我认为select_related方法不会实现您使用此ModelChoiceField实现的目标。你是完全正确的,以下两个查询返回相同的结果查询集:

Catalog.objects.all().select_related('article_products'))
Catalog.objects.all()

Django查询集的select_related方法提供不同的功能,特别是作为性能增强器,以减少获取要从模型实例检索的数据所需的数据库访问次数。 The Django reference about this method包含非常好的文档,其中的示例解释了为什么要将select_related方法用于性能目的。

话虽如此,您的原始目的仍然是:表单字段将显示与给定目录相关的所有文章。

为了实现这一目标,最好过滤给予表单字段的Article对象的查询集。首先,如果我们想在ModelChoiceField中显示Article对象,我们当然应该为ModelChoiceField提供一个包含Article对象而不是Catalog对象的查询集,如下所示:

article = forms.ModelChoiceField(queryset=Article.objects.all())

但是这个查询集参数也不是很正确。我们仍然传递数据库中存在的所有Article对象的查询集。相反,我们只想传递与给定Catalog对象关联的文章。为了实现这一目标,我们可以过滤Article查询集以仅获取与某个Catalog对象相关的Article对象,如下所示:

# cat is some catalog object
article = forms.ModelChoiceField(queryset=Article.objects.filter(catalog=cat))

在此示例中,queryset过滤器仅返回包含对给定Catalog对象的引用的Article对象。此查询集将用于填充ModelChoiceField。

有关按字段查找过滤的详细信息,请see the Django documentation here