Home > Blockchain >  Disable foreign key link in django admin
Disable foreign key link in django admin

Time:12-25

I've got a Django admin site with two models : Client and User (Users are member of a Company working with Clients). Each client has a user referent, so Client has a field 'sales_contact' which is a Foreign Key to User.


class Client(models.Model):
    first_name = models.CharField(max_length=25)
    last_name = models.CharField(max_length=25)
    email = models.EmailField(max_length=100)
    phone = models.CharField(max_length=20)
    mobile = models.CharField(max_length=20)
    company_name = models.CharField(max_length=250)
    date_created = models.DateTimeField()
    date_updated = models.DateTimeField()
    sales_contact = models.ForeignKey(
        to=User,
        on_delete=models.PROTECT,
        limit_choices_to={'role':2}
    )

    def __str__(self):
        return f"{self.first_name}, {self.last_name}"


class ClientAdmin(admin.ModelAdmin):
    fields = ['last_name', 'sales_contact']

A user only having 'view client permission' can however click on the name of the 'sales_contact' (corresponding to a link to the user change view) and will be directed to the 403 Forbidden page.

enter image description here

According to me, it would be preferably to disable this link when user has no change permission.

I tried to use

list_display_links

but it only works with list view, not detailed views.

How to do this, please ?

Livior

CodePudding user response:

You can use 'readonly_fields' to make this amendment in your code

In admin.py do the following according to your code:

class ClientAdmin(admin.ModelAdmin):
    readonly_fields = ['sales_contact']

admin.site.register(Client, ClientAdmin)

This will display the sales_contact field as a read-only field in the Django admin, and the user will not be able to edit the value of the field.

CodePudding user response:

I found ! I had to create a new field, sales_contact_no_link which is a function returning sales_contact with an HTML form without link :

@admin.display
def sales_contact_no_link(self, obj):
    return format_html("{}", obj.sales_contact)

Then, I use get_fields to get the required fields dependant of the user status :

class ClientAdmin(admin.ModelAdmin):
    def get_fields(self, request, obj=None):
        if request.user.is_superuser:
            return ['last_name', 'sales_contact']
        else:
            return ['last_name', 'sales_contact_no_link']

    @admin.display
    def sales_contact_no_link(self, obj):
        return format_html("{}", obj.sales_contact)

And so it works.

  • Related