Django admin内联预取外来关系的外来关系

时间:2016-12-15 21:39:15

标签: python django django-admin

我遇到了相当普遍的问题,即django admin inline会执行大量不必要的查询来填充下拉列表。有4个模型 - 当我查看用户时,我希望看到与该用户关联的UserClientRoles,显示ClientRole名称和客户端。当我只使用角色名称时,它会为每个UserClientRole查询一次(如果有3个分配,则查询3次)。如果我包含客户端名称,它会为每个UserClientRole查询每个客户端名称一次。

我已尝试过此处列出的解决方案(Django admin inline: select_related),但没有骰子。它没有修改行为。我还尝试覆盖UserAdmin类上的get_queryset方法,但没有效果。我尝试过的任何内容都不会减少查询次数。为了简明起见,我删除了一些模型细节。

以下是模特:

class User(models.Model):
    id = models.AutoField(primary_key=True)
    email = models.CharField(unique=True, max_length=200)


class Client(models.Model):
    id = models.AutoField(primary_key=True)
    client_name = models.CharField(unique=True, max_length=200)
    client_identifier = models.CharField(unique=True, max_length=200)


class ClientRole(models.Model):
    client_role_id = models.AutoField(primary_key=True)
    role_name = models.CharField(unique=True, max_length=200)
    client = models.ForeignKey(Client)

    def __unicode__(self):
        return self.role_name + self.client_id.client_name


class UserClientRole(models.Model):
    user_client_role_id = models.AutoField(primary_key=True)
    client_role = models.ForeignKey(ClientRole)
    user = models.ForeignKey(User)

以下是管理模型:

class UserClientRoleFormset(forms.BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        super(UserClientRoleFormset, self).__init__(*args, **kwargs)
        self.queryset = self.queryset.prefetch_related("client_role__client")


class UserClientRoleInline(admin.TabularInline):
    model = UserClientRole
    extra = 1
    formset = UserClientRoleFormset


@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    inlines = (UserClientRoleInline,)

我错过了什么?

1 个答案:

答案 0 :(得分:1)

尝试:

self.queryset.select_related('client_role', 'client_role__client')

Django并不总是最擅长决定选择哪些对象作为查询的一部分,即使你可能认为django ORM足够聪明,因为你正在遍历{{{{{{ 1}},它不是。因此,确保在related_parent__related_childselect_related中指定这两者在过去对我有用。我建议尝试一下!