I would like to create 2 groups (Professors, Students). And I would like to restrict students from creating and deleting Courses.
views.py:
def is_professor(function=None):def _is_professor(u):if user.groups.filter(name='Professor').exists():return Trueelse:raise HttpResponseForbiddenreturn _is_professor(function)class ListCourseView(ListView):model = Coursetemplate_name = 'course_list.html'fields = '__all__'@is_professor
class CreateCourseView(CreateView):def get_queryset(self, request):if not request.user.is_superuser:return Falsemodel = Coursetemplate_name = 'course/edit_course.html'fields = '__all__'def get_success_url(self):return reverse('courses-list')def get_context_data(self, **kwargs):context = super(CreateCourseView, self).get_context_data(**kwargs)context['action'] = reverse('courses-new')return contextclass UpdateCourseView(UpdateView):model = Coursetemplate_name = 'course/edit_course.html'fields = '__all__'def get_success_url(self):return reverse('courses-list')def get_context_data(self, **kwargs):context = super(UpdateCourseView, self).get_context_data(**kwargs)context['action'] = reverse('courses-edit',kwargs={'pk': self.get_object().id})return contextclass DeleteCourseView(DeleteView):model = Coursetemplate_name = 'course/delete_course.html'def get_success_url(self):return reverse('courses-list')
models.py
class Course(models.Model):name = models.CharField(max_length=255,)def __str__(self):return ' '.join([self.name])class UserProfile(models.Model):user = models.OneToOneField(User)picture = models.ImageField(upload_to='profile_images', blank=True)class Meta:permissions = ( ('add_course', 'Add course'), )def __unicode__(self):return self.user.username
This is what I tried. First of all I get an error
NameError: global name 'user' is not defined.
And secondly I still don't think this would work :)
Something that i did for one of my django project is :
I defined a function that will check permissions and if user is authenticated :
from django.contrib.auth.decorators import user_passes_testdef group_required(*group_names):"""Requires user membership in at least one of the groups passed in."""def in_groups(u):if u.is_authenticated():if bool(u.groups.filter(name__in=group_names)) | u.is_superuser:return Truereturn Falsereturn user_passes_test(in_groups, login_url='403')
And then i passed this function as decorator for my functions :
from whatever import group_required@group_required('Professor')
def action_only_for_professor(request):# do things@group_required('Student')
def action_only_for_student(request):# do other things
With this method you can declare multi-group for your functions like this :
@group_required('Professor', 'Student', 'Administrator', ...)
This trick work only with method that you create.
if you want to do the same for class, i suggest you to check django-braces (e.q. http://django-braces.readthedocs.org/en/latest/index.html).
Django Braces works like this :
from braces.views import GroupRequiredMixinclass CreateCourseView(CreateView, GroupRequiredMixin):group_required = u"Professor"def get_queryset(self, request):if not request.user.is_superuser:return Falsemodel = Coursetemplate_name = 'course/edit_course.html'fields = '__all__'def get_success_url(self):return reverse('courses-list')def get_context_data(self, **kwargs):context = super(CreateCourseView, self).get_context_data(**kwargs)context['action'] = reverse('courses-new')return context
If you want to use more than one group permission in your class, just do it like this :
group_required = [u"Professor", u"Student", u"Administrator", etc...]
Django-braces is very powerful to check permissions for your class, in the sense that you can check if a user is authenticated (with LoginRequiredMixin), is anonymous (AnonymousrequiredMixin), is superuser (SuperuserRequiredMixin), got one (PermissionRequiredMixin) or multiple permissions (MultiplePermissionRequiredMixin), and more and more stuff ! You just have to inherit your class with the appropriate mixin you want to use ;)
Hope it will help, and waiting for your return about all that :)