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.
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.