Django and programming noob here. I've made an application I'd like to deploy, but I need to figure out how to limit access to the UpdateView to the creator of that object, and I'm stumped.
Currently a user can use the CreateView .../universities/create/ to create a university object, but then any user can use .../universities/update/ to edit that object. I want to configure this so only the user who is the creator (any user with the ManytoMany attribute 'administrator') of that university has access to the UpdateView for their university object.
Any advice would be appreciated. I've spent a few days on this and I haven't made much traction...thanks for reading.
models.py
class University(models.Model):
name = models.CharField(max_length=100)
about = models.TextField()
administrators = models.ManyToManyField(User)
profile_picture = models.FileField(upload_to=get_upload_file_name, blank=True)
def __unicode__(self):
return unicode(self.name)
def get_absolute_url(self):
return reverse('university_detail', kwargs={'pk': str(self.id)})
views.py
class UniversityCreateView(CreateView):
model = University
form_class = UniversityForm
template_name = 'university_create.html'
def form_valid(self, form):
f = form.save(commit=False)
f.save()
return super(UniversityCreateView, self).form_valid(form)
class UniversityUpdateView(UpdateView):
model = University
form_class = UniversityForm
template_name='university_form.html'
youll have to include permission decorators on your views , further info is here https://docs.djangoproject.com/en/dev/topics/auth/ , & https://docs.djangoproject.com/en/dev/topics/auth/default/#topic-authorization
so if you want to limit your updateview to any user with the ManytoMany attribute 'administrator', youll have to do something like this:
views.py
from appname.users.decorators import requiresGroup
from django.contrib.auth.decorators import login_required
class UniversityUpdateView(UpdateView):
model = University
form_class = UniversityForm
template_name='university_form.html'
@method_decorator(requiresGroup("groupname" , login_url='/accounts/login/'))
def dispatch(self, request, *args, **kwargs):
return super(UniversityUpdateView, self).dispatch(request, *args, **kwargs)
also if you havent already youll have to include the following at the top of your models.py
from django.contrib.auth.modes import user
though Ill assume its there as youve defined your administrators with the user model
then go to the group seetings in the django admin ( should be a url like localhost/admin/auth/group , add your special adminstrator group name, then go to the admin user section (localhost/admin/auth/user), then make sure they have been put into the adminstrator group
then replace "groupname" in the @requiresGroup decorator with the actual name of the user group
the @requiresGroup decorator isnt a standard decorator, so it has to be written
make a folder path and file like appname/users.decorators.py then in decorators.py write
from functools import update_wrapper , wraps
from django.utils.decorators import available_attrs
from django.http import HttpResponse, HttpResponseRedirect
def requiresGroup(groupname):
def decorator(view_function):
def _wrapped_view(request,*args,**kwargs):
if request.user.groups.filter(name=groupname).count()!=1:
return HttpResponseRedirect("/")
else:
return view_function(request,*args,**kwargs)
return wraps(view_function,assigned=available_attrs(view_function))(_wrapped_view)
return decorator
hope this helped
edit: made a mistake, put the decorators above the class, they should be in a function inside the class, noticed my mistake almost immediately so hopefully I havent caused any trouble
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With