Ответ @ Slipstream показывает , как реализовать решение, а именно. переопределяя атрибуты для виджета поля формы, но, на мой взгляд, get_form
не самое логичное место для этого.
Ответ @ cethegeek показывает , где для реализации решения, а именно. в расширении formfield_for_dbfield
, но не дает явного примера.
Зачем использовать formfield_for_dbfield
? Его строка документа предполагает, что это назначенный крюк для работы с полями формы:
Хук для указания экземпляра поля формы для данного экземпляра поля базы данных.
Он также позволяет (чуть-чуть) чище и яснее код, и, в качестве бонуса, мы можем легко установить дополнительные атрибуты Field
формы , такие как значение initial
и / или disabled
(пример здесь ), добавив их к kwargs
(перед вызовом super
).
Итак, объединяя два ответа (при условии, что модели ОП ModelA
и ModelB
, а поле модели ForeignKey
называется b
):
class ModelAAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, request, **kwargs):
# optionally set Field attributes here, by adding them to kwargs
formfield = super().formfield_for_dbfield(db_field, request, **kwargs)
if db_field.name == 'b':
formfield.widget.can_add_related = False
formfield.widget.can_change_related = False
formfield.widget.can_delete_related = False
return formfield
# Don't forget to register...
admin.site.register(ModelA, ModelAAdmin)
ПРИМЕЧАНИЕ. Если в поле модели ForeignKey
указано on_delete=models.CASCADE
, атрибут can_delete_related
по умолчанию равен False
, как видно из source для RelatedFieldWidgetWrapper
.