【问题标题】:django admin and inlines: many-to-many with 'through' model - performance issuedjango 管理员和内联:使用“通过”模型的多对多 - 性能问题
【发布时间】:2016-01-03 06:05:57
【问题描述】:

我有一个 m2m 字段的问题,该字段使用中间模型(“通过”)与管理员和内联。这是代码:

# MODELS

class Engagement(models.Model):
    parent_engagement = models.ForeignKey('self', blank=True, null=True, related_name='child_engagements')
    title = models.CharField('Engagement title', max_length=200)
    ...
    # client
    client = models.ForeignKey(Client, related_name='engagements')
    primary_point_of_contact = models.ForeignKey(
        ClientContact, null=True, blank=True,
        related_name='engagements_for_which_point_of_contact'
    )
    additional_point_of_contacts = models.ManyToManyField(
        ClientContact,
        through='AdditionalPointOfContact'
    )
    .... # other fields


class ClientContact(models.Model):
    first_name = models.CharField(max_length=200, blank=True)
    last_name = models.CharField(max_length=200, blank=True)
    jobtitle = models.CharField(max_length=200, blank=True)
    company = models.ForeignKey(Client, null=True, blank=True)


class AdditionalPointOfContact(models.Model):
    engagement = models.ForeignKey("Engagement", related_name='additional_points_of_contact')
    client_contact = models.ForeignKey("ClientContact")
    description = models.CharField(max_length=500, blank=True)

    def __unicode__(self):
        return self.client_contact.__unicode__()



# ADMIN

class EngagementAdmin(ChaosDefaultAdmin):
    ....
    inlines = [
        ScopeServiceElementAdmin,
        AdditionalPointOfContactInlineAdmin
    ]
    list_display = (...


class AdditionalPointOfContactInlineAdmin(admin.TabularInline):

    model = AdditionalPointOfContact
    fieldsets = [
        ('', {
            'fields': (('client_contact',),
                       ('description',),)
        }),
    ]

    extra = 0
    min_num = 0

根据django-debug-toolbar,sql 选项卡显示8382 个查询,而注释掉AdditionalPointOfContactInlineAdmin 它减少到10 个查询,所以那里有问题。 我可能会覆盖AdditionalPointOfContactInlineAdmin 的get_queryset 方法,但我不知道具体如何以及为什么。有什么建议吗?

【问题讨论】:

    标签: django django-models django-admin django-queryset django-orm


    【解决方案1】:

    尝试覆盖 EngagementAdmin.get_queryset():

    class EngagementAdmin(ChaosDefaultAdmin):
        def get_queryset(self, request):
            qs = super(EngagementAdmin, self).get_queryset(request)
            return qs.prefetch_related('additional_points_of_contact')
            # or 
            # return qs.prefetch_related('additional_points_of_contact__client_contact')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-06-10
      • 2014-09-01
      • 2011-11-16
      • 2013-04-06
      相关资源
      最近更新 更多