是否有一种简单的方法可以让Django使用单个SQL查询填充外键的下拉列表?
考虑以下模型;
class Site(models.Model):
code = models.CharField(max_length=5)
name = models.CharField(max_length=45)
def __unicode__(self):
return u'%s - %s' % (self.code, self.name)
class Location(models.Model):
site = models.ForeignKey(Site)
name = models.CharField(max_length=45, verbose_name='Location Name')
def __unicode__(self):
return u'%s - %s' % (self.site, self.name)
其他模型则包含models.ForeignKey(Location)
,并选择这些模型以admin.ModelAdmin
形式呈现为下拉列表。
使用django-debug-toolbar我可以看到在填充下拉列表时,我为每个具有site_id
值的Location项执行了以下查询;
SELECT
`myApp_site`.`id`,
`myApp_site`.`code`,
`myApp_site`.`name`
FROM `myApp_site`
WHERE `myApp_site`.`id` = 1
我可以看到这是因为我在self.site
中使用def __unicode__(self)
,因为我想查看每个位置的网站。
我尝试在list_select_related = True
中使用admin.ModelAdmin
,但这仅适用于实例上的相关数据,而不适用于表单中的可能值。
通常,整个外键下拉列表可以从单个查询填充,如;
SELECT
`myApp_location`.`id`,
`myApp_location`.`name`,
`myApp_site`.`code`,
`myApp_site`.`name`
FROM `myApp_site`
INNER JOIN `myApp_site` ON (`myApp_location`.`site_id` = `myApp_site`.`id`)
我可以强制使用位置模型select_related()
并消除查询吗?
有没有更好的方法来包含网站的位置或减少Django正在执行的查询数量?
我是否陷入了Django反模式?我有几个像这样的外键字段,我担心随着数据库的填满,查询的数量会增加。
答案 0 :(得分:0)
尝试在AdminClass上使用formfield_for_foreignkey方法,在那里你可以覆盖ForeignKey的查询集。见下面的例子
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'location':
kwargs["queryset"] = Location.objects.select_related('site').all()
return super(ModelWithLocationAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)