2

有没有一种简单的方法让 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.siteindef __unicode__(self)因为我想查看每个位置的站点。

我尝试在 中使用list_select_related = Trueadmin.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`)

我可以强制 Location 模型使用select_related()和消除查询吗?

有没有更好的方法将站点包含在位置中或减少 Django 正在执行的查询数量?

有没有我陷入的 Django 反模式?我有几个像这样的外键字段,我担心随着数据库填满查询数量会增加。

4

1 回答 1

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)
于 2013-12-16T10:02:06.400 回答