Making a field readonly according to the user in admin.py

340 views
Skip to first unread message

Victor

unread,
Nov 18, 2015, 5:16:10 AM11/18/15
to django...@googlegroups.com
Dear experts,

models.py

class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
quantity = models.IntegerField(db_column='quantitity',default=0)
class Meta:
db_table="book"

admin.py

class BookOption(admin.ModelAdmin):
list_display = ('title', 'author', 'quantity')
fields=(('title', 'author'), ('quantity'))
order_by= ['title', ]

admin.site.register(Book,BookOption)


I'm trying to explain my problem with the simple example above.
Let's suppose that I have two staff users 'victor' and 'roby' and I want that the fields 'author and 'quantity' be readonly when user 'roby' is logged in and readwrite for user 'victor'
How can I achieve this result if possible with something of the following simple kind


class BookOption(admin.ModelAdmin):
if (user is 'roby'):
readonly_fields=['quantity',]
list_display = ('title', 'author', 'quantity')
fields=(('title', 'author'), ('quantity'))
order_by= ['title', ]

Thanks
Vittorio

Jani Tiainen

unread,
Nov 18, 2015, 5:21:55 AM11/18/15
to django...@googlegroups.com
Hi,

In general you shouldn't be even trying to do this in admin since it's
not designed for this kind of functionality.

Admin is just a datacentric tool to view your data. It's never been
meant to help implementing any businesslogic. And basically you only
should let people in admin that you trust full 100%.

If you can't trust them (which is indicated by "readonly field"
requirement) you should do custom view and templates for that. Generic
class based views can greatly help you to achieve it, and most probably
with really less effort than trying to do that in admin.
--

Jani Tiainen

Timothy W. Cook

unread,
Nov 18, 2015, 7:33:07 AM11/18/15
to django...@googlegroups.com
While Jani's admonishments might be considered 'best practice' in some cases. Those do not always cover everyone's use case.
 
I solved a similar issue allowing users with the superuser role to have edit access to some items that other staff do not have access to edit. 

Use the get_form method of the ModelAdmin and select the form to call. 

For example:
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['form'] = DMAdminSUForm
        else:
            kwargs['form'] = DMAdminForm

Then in each form you can set the readonly attributes and any other user role specific functionality you need. 

HTH,
Tim




  




--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/564C5123.1020501%40gmail.com.

For more options, visit https://groups.google.com/d/optout.



--

============================================
Timothy Cook
LinkedIn Profile:http://www.linkedin.com/in/timothywaynecook

Mike Dewhirst

unread,
Nov 18, 2015, 2:56:53 PM11/18/15
to django...@googlegroups.com
These three references should get you started.

get_queryset[1] is useful for filtering the entire display based on the
request user.

readonly_fields[2] is a simple list of fields which are readonly for
everyone.

get_readonly_fields[3] is an Admin callable which can be overridden by
your own method provided your method has the same (request, obj)
signature. In admin.py you would say get get_readonly_fields =
my_get_readonly_fields

I agree with Jani that you will be better off in the long run building
your own interface ... but ymmv

[1]
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_queryset

[2]
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields

[3]
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_readonly_fields

Mike

Hugo Osvaldo Barrera

unread,
Nov 19, 2015, 8:48:22 AM11/19/15
to django...@googlegroups.com
> --

I generally solve this via

get_readonly_fields(request, obj):
if request.user.has_perm(...):
return ('somefield',)
return ()

--
Hugo Osvaldo Barrera
Reply all
Reply to author
Forward
0 new messages