如何在 Django Admin 中使用 can_add_lated

问题描述 投票:0回答:6

我在这里阅读了有关can_add_相关功能的信息:https://code.djangoproject.com/ticket/9071

我尝试这样使用它:

def get_form(self, request, obj=None, **kwargs):
    self.fields['person'].can_add_related = False
    return super(OperationAdmin, self).get_form(request, obj, **kwargs)

但这会引发 TypeError,我不知道如何解决这个问题。

有人能指出我正确的方向吗?

谢谢你。

python django django-admin
6个回答
21
投票

这可能来得晚了。但供其他观众参考,

def get_form(self, request, obj=None, **kwargs):
    form = super(ProductAdmin, self).get_form(request, obj, **kwargs)
    form.base_fields['category'].widget.can_add_related = False
    return form

3
投票

can_add_related
似乎是 小部件上的属性,而不是字段,所以请尝试:

self.fields['person'].widget.can_add_related = False

1
投票

替代方法,在实例化表单*之前*更改小部件选项:

class MyAdmin(django.contrib.admin.ModelAdmin):

    def formfield_for_dbfield(self, *args, **kwargs):
        formfield = super().formfield_for_dbfield(*args, **kwargs)
        if hasattr(formfield, "widget"):
            formfield.widget.can_add_related = False
            formfield.widget.can_delete_related = False
            formfield.widget.can_change_related = False
        else:
            pass  # this relation doesn't have an admin page to add/delete/change

        return formfield

1
投票

另一种方法,如果您正在定义内联模型并在管理中使用它,则覆盖 get_formset 方法:

from django.contrib import admin


class MyModelInline(admin.TabularInline):
    model = MyModel
    extra = 0
    min_num = 1
    max_num = 10
    fields = [
        'some_field'
    ]

    def get_formset(self, request, obj=None, **kwargs):
        fs = super().get_formset(request, obj, **kwargs)
        fs.form.base_fields['some_field'].widget.can_add_related = False
        fs.form.base_fields['some_field'].widget.can_change_related = False
        fs.form.base_fields['some_field'].widget.can_delete_related = False
        return fs

0
投票

对于 TabularInline 您可以结合 @Art 和 @babis21 的答案:

我们也可以在这里使用@Art 答案以及使用以下内容:

    def get_formset(self, request, obj=None, **kwargs):
        res = super().get_formset(request, obj=None, **kwargs)
        for formfield in res.form.base_fields.values():
            if hasattr(formfield, "widget"):
                formfield.widget.can_add_related = False
                formfield.widget.can_delete_related = False
                formfield.widget.can_change_related = False
        return res

0
投票

我编写了这个 mixin:

class AdminModelNoAddOrChangeForeignKeyMixin:
    # For admin.ModelAdmin
    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        for field_name, field in form.base_fields.items():
            if isinstance(self.model._meta.get_field(field_name), ForeignKey):
                field.widget.can_add_related = False
                field.widget.can_change_related = False
        return form

    # For admin.TabularInline and admin.StackedInline
    def get_formset(self, request, obj=None, **kwargs):
        fs = super().get_formset(request, obj, **kwargs)
        for field_name, field in fs.form.base_fields.items():
            if isinstance(self.model._meta.get_field(field_name), ForeignKey):
                field.widget.can_add_related = False
                field.widget.can_change_related = False
        return fs

适用于所有外键字段,作为 Inline 和 ModelAdmin 的混合:

class MyInline(AdminModelNoAddOrChangeForeignKeyMixin, admin.TabularInline):
    whatever

class DigitalDistributionDataAdmin(AdminModelNoAddOrChangeForeignKeyMixin, admin.ModelAdmin):
    whatever
  
© www.soinside.com 2019 - 2024. All rights reserved.