【问题标题】:Django __unicode__ and FK is very slowDjango __unicode__ 和 FK 很慢
【发布时间】:2012-03-04 22:39:51
【问题描述】:

如果我写类似的东西

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 中有足够的条目可供我在管理页面中单击的供应商,则该页面可能需要几分钟!

有什么方法可以减少管理页面上的数据库点击次数?

【问题讨论】:

    标签: python sql django performance admin


    【解决方案1】:

    您的问题来自这样一个事实,即每次您在 ComponentType 实例上调用 __unicode__ 时,Django 都会进行数据库调用。

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

    1. 您覆盖了ProductInlinequeryset 方法以包含select_related('ChipStepping')(Django 1.3 及更高版本)。
    2. 或者,如果您也想在其他地方解决此问题,您可能需要更改 ComponentType 的默认管理器 (objects) get_query_set 方法,使其包含 select_related 调用。

    【讨论】:

    【解决方案2】:

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

    似乎对每一行的选择都进行了评估,因此使用 formfield_for_dbfield 您可以按照链接中的建议缓存选择。这节省了去数据库渲染foreign_keys的每个下拉/选择框

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 2013-05-13
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      相关资源
      最近更新 更多