15π
Itβs not exactly a documented feature. Furthermore, formfield_for_dbfield is a damned mess (just as most of the django.contrib.admin
). But itβs the cleanest approach I found, and it works fine for me.
class MyAdmin(django.contrib.admin.ModelAdmin):
def formfield_for_dbfield(self, *args, **kwargs):
formfield = super().formfield_for_dbfield(*args, **kwargs)
formfield.widget.can_delete_related = False
formfield.widget.can_change_related = False
# formfield.widget.can_add_related = False # can change this, too
# formfield.widget.can_view_related = False # can change this, too
return formfield
9π
in admin.py create a def under your model ModelAdmin class. Choose the options for Add, Change or Delete related to the foreign_key field, keeping the ones you desire to hide and deleting (or changing boolean from False to True) for the ones you wante to show:
class YourModelAdmin(admin.ModelAdmin):
...
def get_form(self, request, obj=None, **kwargs):
form = super(YourModelAdmin, self).get_form(request, obj, **kwargs)
field = form.base_fields["your_foreign_key_field"]
field.widget.can_add_related = False
field.widget.can_change_related = False
field.widget.can_delete_related = False
return form
- Is it possible to force queryset evaluation while keeping it a queryset
- Hosting Django app with Waitress
- Serializer validate function is not called DRF
- CSRF verification Failed β Referer is insecure while host is secure
4π
(Transferring my comment to an answer)
The above answers work great for regular admin pages. To get this to work in an admin inline (ex: admin.StackedInline
), use get_formset
instead of get_form
:
def get_formset(self, request, obj=None, **kwargs):
formset = super().get_formset(request, obj, **kwargs)
field = formset.form.base_fields["your_foreign_key_field"]
field.widget.can_add_related = False
field.widget.can_change_related = False
field.widget.can_delete_related = False
return formset
- How does Django foreign key access work
- Reading multidimensional arrays from a POST request in Django
- TypeError object is not iterable
- Django_auth_ldap no module named ldap
- Django: Custom User Model fields not appearing in Django admin
3π
Just to add to the completeness of Artβs answer:
For an Inline (admin.StackedInline
, admin.TabularInline
) you can use formfield_for_dbfield as well:
class MyInline(django.contrib.admin.TabularInline):
def formfield_for_dbfield(self, *args, **kwargs):
formfield = super().formfield_for_dbfield(*args, **kwargs)
if formfield:
formfield.widget.can_delete_related = False
formfield.widget.can_change_related = False
formfield.widget.can_add_related = False
formfield.widget.can_view_related = False
return formfield
formfield
is somehow None
sometimes for Inlines so you need to add the if statement.
- Django : Static content not found
- Using django-rest-interface with http put
- Domain Driven Design Onion Architecture with Django Rest Framework
- Django-Storages S3 with minio as backend
0π
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['xxx'].widget.can_delete_related = False