Django __unicode__和FK非常慢

时间:2012-02-13 14:17:20

标签: python sql django performance admin

如果我写了类似

的内容
class Chip(models.Model):
  name      = models.CharField(max_length=16)
  shortname = models.CharField(primary_key=True, unique=True, max_length = 16)

  def __unicode__(self):
    return self.shortname

class ChipStepping(models.Model):

  stepping = models.CharField (max_length=16)
  ChipShortname = models.ForeignKey('Chip', db_column="ChipShortname")

  def __unicode__(self):
    return "%s:%s" % (self.ChipShortname, self.stepping)

class ComponentType(models.Model):
  name         = models.CharField (max_length=32)
  ChipStepping = models.ForeignKey('ChipStepping', db_column="ChipStepping")

  def __unicode__(self):
    return "%s(%s)" % (self.name, self.ChipStepping);

class ComponentVendor(models.Model):
  name     = models.CharField      (unique=True, max_length=16)
  products = models.ManyToManyField('ComponentType', through='ComponentVendorProduct', related_name='vendors')

  def __unicode__(self):
    return "%s" % (self.name)

class ComponentVendorProduct(models.Model):
  ComponentVendor = models.ForeignKey('ComponentVendor', db_column="ComponentVendor")
  ComponentType   = models.ForeignKey('ComponentType'  , db_column="ComponentType")

尝试为ComponentVendor

创建管理页面
class ProductInline(admin.TabularInline):
  model = ComponentVendor.products.through
  extra = 0

class ComponentVendorAdmin(admin.ModelAdmin):
  inlines = [ProductInline]
  list_filter = ['products__name']
  exclude = ['products']

admin.site.register(ComponentVendor, ComponentVendorAdmin)

生成的页面最多可能需要30秒。载入 从我做过的一些调试中,我发现它反复为ChipStepping和Chip做出冗余的单一查询,在where子句中使用相同的参数,而不是智能地构建一个可以查找所有数据的查询。

如果我从ChipStepping和ComponentType的 unicode 函数中删除外键引用,则会减少此问题

如果我在管理页面中点击供应商的ComponentVendorProducts中有足够的条目,该页面可能需要几分钟!

有没有办法可以减少管理页面上的数据库点击次数?

2 个答案:

答案 0 :(得分:6)

你的问题来自于每当你在__unicode__实例上调用ComponentType时,Django正在进行数据库调用。

您的问题有两个解决方案:

  1. 您覆盖ProductInline的{​​{1}}方法以包含queryset(Django 1.3及更高版本)。
  2. 或者,如果您也想在其他地方解决问题,可能需要更改select_related('ChipStepping')的默认管理员(ComponentTypeobjects方法,使其包含{{ 1}}来电。

答案 1 :(得分:0)

您可能还想查看此处给出的建议: http://blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/

似乎每行都会评估选项,因此使用formfield_for_dbfield可以按照链接中的建议缓存选项。这将保存到db以呈现foreign_keys的每个下拉列表/选择框