为什么django admin inline保存在inline包含只读主键时失败?

ckocjqey  于 2023-04-22  发布在  Go
关注(0)|答案(2)|浏览(89)

为什么在django admin中不能有一个readonly内联相关对象?
在下面的示例中,只要我在readonly_fields中添加id,它就会在尝试保存OtherFoo模型时中断。
我在几年前关闭的django项目中发现了这个ticket,备用票没有帮助。

class FooInline(admin.TabularInline):
    model = Foo

    fields = (
        "id",
        "link",
        "content",
    )
    readonly_fields = (
        "id", # <===============
        "link",
        "content",
    )

class OtherFooAdmin(admin.ModelAdmin):

    inlines = [
        FooInline,
    ]
isr3a4wc

isr3a4wc1#

如果我没记错的话,当表单发布时,只读字段实际上并没有发布它们的值。我所做的是修复这个问题,制作一个自定义的管理表单,它有一个自定义的clean方法,可以将该值注入表单。
这是我自己的代码:

class FooAdminForm(forms.ModelForm):
    class Meta:
        model = Foo
        exclude = ['name']

    def __init__(self,  *args, **kwargs):
        super(FooAdminForm, self).__init__(*args, **kwargs)
        if kwargs.get('id') or 'id' in kwargs.get('initial'):
            self.fields['id'].widget.attrs={'class': 'form-control', 'readonly': 'true'}
        return self

    def clean_id(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            return instance.id
        else:
            return self.cleaned_data['id']
igetnqfo

igetnqfo2#

我遇到了一个类似的问题。我使用以下方法解决了它:

class FooAdminForm(forms.ModelForm):
    class Meta:
        model = Foo
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super(FooAdminForm, self).__init__(*args, **kwargs)
        self.fields['id'].widget.attrs['readonly'] = True

class FooInline(admin.StackedInline):
    model = Foo
    extra = 0
    form = FooAdminForm

    fieldsets = ((None, {"fields": (
        "id",
        "field_a",
        "field_b",

     )}),)

@admin.register(FooBarModel)
class FooBarModelAdmin(admin.ModelAdmin):
    inlines = [FooInline]

相关问题