Django access control based on model field value
I have a model class Department
with a field name
. I have another Student
foreign key model Department
. I want to control access to objects Student
based on department. That is, a user with edit permission for the department named "CS" can only edit these fields. How can this be achieved in Django? (I am using django 1.8, python3)
Edit
class Department(models.Model):
name = models.CharField(_('department name'), max_length=255)
class Students(models.Model):
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30)
department = models.ForeignKey('Department')
Also I create the required permissions dynamically when adding a new department (for example: if department.name for a new record is "CS", 2 permissions of type "view_CS" and "edit_CS" will be created)
source to share
Based on http://django-guardian.readthedocs.org/en/v1.2/userguide/assign.html#for-group
class Department(models.Model):
name = models.CharField(_('department name'), max_length=255)
class Meta:
permissions = (
('view', 'View department'),
('edit', 'Edit department'),
)
Somewhere in the views :
from django.contrib.auth.models import Group
cs_department = Department.objects.get(name='cs_department')
cs_department_group = Group.objects.create(name=cs_department.name)
assign_perm('view', cs_department_group, cs_department)
assign_perm('edit', cs_department_group, cs_department)
request.user.groups.add(cs_department_group)
print(request.user.has_perm('view', cs_department)) # True
print(request.user.has_perm('edit', cs_department)) # True
source to share
Since my application is quite large, I cannot afford to change all data references to accommodate the permissions as @madaohan answer.
This kind of access control mechanisms can be easily used to define a custom model manager ( docs ) and login middleware for custom object in models ( Check this link ).
source to share