'django admin: how to disable edit and delete link for foreignkey

In django admin site, if the model has a foreignkey, by default it will be a select input and there are three links(edit, add, delete) like below. How to disable these links only for foreignkey? If using has_delete_permission, they it cannot be deleted in its own change form either.

Default: default

Expected: after



Solution 1:[1]

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

Solution 2:[2]

(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

Solution 3:[3]

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['xxx'].widget.can_delete_related = False

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Guaracy Lima
Solution 2
Solution 3 Ron