5

I have the following model defined:

class PRegistration(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    create_date = models.DateTimeField(auto_now=False, auto_now_add=True)
    teamName = models.CharField(max_length=144)
    city = models.CharField(max_length=144)

How do I make all these fields read only in the admin page for all staff accounts except the superuser? I wanna do this without specifying the fields one by one so that I can reuse the code in multiple places.

NKS
  • 165
  • 1
  • 8
  • you might read through the official django documentation on the admin site: https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields – glotchimo Sep 15 '18 at 22:57
  • This answer should give you the solutions: https://stackoverflow.com/questions/13817525/django-admin-make-all-fields-readonly – ger.s.brett Sep 16 '18 at 06:55

3 Answers3

10

Add the following function in the ModelAdmin subclass that you make in admin.py . The get_read_only function returns a list or a tuple which tells the fields that are to be made readonly. In the following code, the non-superuser staff accounts will see all fields as readonly, while the superuser will be able to edit all of those fields.

def get_readonly_fields(self, request, obj=None):
    if request.user.is_staff:
        if request.user.is_superuser:
            return []
        else:
            return [f.name for f in self.model._meta.fields]

Special thanks: this question and its answers

NKS
  • 165
  • 1
  • 8
3

If Your model.py contains

class PRegistration(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    create_date = models.DateTimeField(auto_now=False, auto_now_add=True)
    teamName = models.CharField(max_length=144)
    city = models.CharField(max_length=144)

If you want to make field user, teamName readonly for other staffs except superuser. Add this code on your admin.py of same app.

@admin.register(PRegistration)
class PRegistrationAdmin(admin.ModelAdmin):
    list_display = ['user']
    search_fields = ['user']
    readonly_fields = ['user', 'teamName']

    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return []
        return self.readonly_fields
0

You can override the get_readonly_fields() method of AdminModel class:

from django.contrib import admin
from core import models

class UserAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return [] # list of read only fields name
        else:
            return ['your fields names'] # list of read only fields name

admin.site.register(models.User, UserAdmin)
Antoine
  • 1,393
  • 4
  • 20
  • 26
Tintin
  • 51
  • 6