Почему django admin inline save не работает, когда inline содержит readonly первичный ключ?

Почему невозможно иметь readonly inline related object в админке django?

В примере ниже, как только я добавляю id в readonly_fields, он ломается при попытке сохранить OtherFoo модель.

Я нашел этот тикет в проекте django, который был закрыт несколько лет назад, и альтернативный тикет не помогает.

class FooInline(admin.TabularInline):
    model = Foo

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

class OtherFooAdmin(admin.ModelAdmin):

    inlines = [
        FooInline,
    ]

Если я правильно помню, поля readonly на самом деле не публикуют свои значения, когда форма опубликована. Чтобы исправить это, я сделал пользовательскую форму администратора, которая имеет пользовательский метод очистки, который как бы вставляет значение обратно в форму.

Это взято из моего собственного кода:

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']

Я столкнулся с аналогичной проблемой. Я решил ее, используя следующее:

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]
Вернуться на верх