在管理员更改页面中为列表字段设置自定义查询集(select_related)?

时间:2017-02-03 10:34:56

标签: python django django-models django-admin

我有一个使用Django管理界面来管理很多对象,而且其中一个页面给了我一个问题,这个页面有一个字段指向一个__str__的相关对象(外键)也转到它的相关对象,这会产生很多查询并且几乎无法使用(大约3000个查询显示页面,因为有很多对象)。

我想知道是否有办法设置自定义查询集?我想为这个元素添加一个select_related或prefetch_related。

导致问题的部分是此证书申请清单:

enter image description here

页面模型(证书具有以下属性:

class Certificate(models.Model):

    certificate_request = models.OneToOneField(
        "CertificateRequest",
        verbose_name=_("Certificate request"),
        related_name="certificate",
        blank=True,
        null=True
    )

相关模型有:

class CertificateRequest(models.Model):

    domain = models.ForeignKey(
        "Domain",
        verbose_name=_("Domain"),
        related_name="certificate_requests"
    )

    def __str__(self):
        return "{state} certificate request for {domain} from {creation_date}".format(
            state=dict(self.STATUS).get(self.status),
            domain=self.domain.fqdn,
            creation_date=self.creation_date
        )

解决这个问题的方法是什么?如何在此部分设置查询集?

编辑:我添加了更多信息。 我尝试使用自定义表单,但这没有做任何改变:

class CertificateForm(forms.ModelForm):
    certificate_request = forms.ModelChoiceField(queryset=CertificateRequest.objects.select_related("domain"))

    class Meta:
        model = Certificate
        fields = "__all__"


@admin.register(Certificate)
class CertificateAdmin(CompareVersionAdmin):
    model = Certificate

    class Meta:
        form = CertificateForm

2 个答案:

答案 0 :(得分:1)

您可以为管理员创建custom ModelForm,为ForeignKey指定ModelChoiceField。您可以在此处指定queryset参数:

# forms.py
class MyForm(forms.ModelForm):
    certificate_request = forms.ModelChoiceField(queryset=CertReq.objects.foo().bar())
    #                                               select/prefetch-------^^^^^^^^^^^

    class Meta:
        model = Foo

# admin.py
class YourAdmin(ModelAdmin):
    form = MyForm

答案 1 :(得分:0)

ModelAdmin类上的get_object method负责检索要编辑的对象。您当然可以在子类中扩展该方法,以便在必要时使用select_related。