Need help in calling dispatch on custom mixin for authorization

118 views
Skip to first unread message

Ajat Prabha

unread,
Jun 12, 2017, 12:24:25 PM6/12/17
to Django users
Hi there,
I'm learning django and creating a forum for this purpose, now I have a Topic model and I want to create an UpdateView for it, but what I want is that a user should be logged in and owner of that topic, only then the author can edit it. For login part, I'm using LoginRequiredMixin and for Topic authorization, I'm trying to create custom mixin UserAuthorMixin, but I'm having trouble to get it working. The implementation below works same for author's own topics and other author's post.

views.py

from django.views import generic
from django.views.generic.edit import CreateView, UpdateView
from .models import Topic
from .forms import TopicForm
from django.core.urlresolvers import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from hitcount.views import HitCountDetailView
from .mixins import UserAuthorMixin

class HomeRedirectView(generic.RedirectView):
    url = reverse_lazy('forum:index')

class IndexView(LoginRequiredMixin, generic.ListView):
    model = Topic
    template_name = 'index.html'
    context_object_name = 'topic_list'

class TopicDetailView(LoginRequiredMixin, HitCountDetailView, generic.DetailView):
    model = Topic
    count_hit = True
    context_object_name = 'topic'
    template_name = 'topicdetail.html'
    def get_context_data(self, **kwargs):
        context = super(TopicDetailView, self).get_context_data(**kwargs)
        context['answer_list'] = self.object.answer_set.all()
        return context

class TopicCreateView(LoginRequiredMixin, CreateView):
    form_class = TopicForm
    template_name = 'topic_form.html'
    def form_valid(self, form):
        form.instance.owner = self.request.user.userprofile
        return super(TopicCreateView, self).form_valid(form)

class TopicUpdateView(UserAuthorMixin, UpdateView):
    model = Topic
    form_class = TopicForm
    template_name = 'topic_form_edit.html'

mixins.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied

class UserAuthorMixin(LoginRequiredMixin):
    def dispatch(self, request, *args, **kwargs):
        # something is wrong after this
        if request.user.is_authenticated() and request.user is not self.get_object().owner.user:
            raise PermissionDenied
        return super(UserAuthorMixin, self).dispatch(request, *args, **kwargs)

models.py

from django.db import models
from oauth.models import UserProfile
from ckeditor_uploader.fields import RichTextUploadingField
from django.core.urlresolvers import reverse
from hitcount.models import HitCountMixin

class Topic(models.Model, HitCountMixin):
    # Choices
    CAT_CHOICES = (
        ('Q', 'Question'),
        ('F', 'Feedback'),
    )
    # Topic Database Model
    author = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
    category = models.CharField(max_length=3, choices=CAT_CHOICES, default='Q')
    title = models.CharField(max_length=256)
    content = RichTextUploadingField(blank=True)
    tags = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)
    @property
    def number_of_answers(self):
        return self.answer_set.count()
    def get_absolute_url(self):
        return reverse('forum:detail', kwargs={'pk': self.pk})
    def __str__(self):
        return self.title


Also if there is some other better way to accomplish this, please tell me that.
Thanks!

Ajat Prabha

unread,
Jun 14, 2017, 1:05:16 PM6/14/17
to Django users
Can someone point out what is wrong in the code?

Ajat Prabha

unread,
Jun 15, 2017, 5:09:33 AM6/15/17
to Django users
There's a typo
in

if request.user.is_authenticated() and request.user is not self.get_object().owner.user:
It is
if request.user.is_authenticated() and request.user is not self.get_object().author.user: 
But still, it doesn't work. Same issue persists.

Ajat Prabha

unread,
Jun 15, 2017, 6:02:21 AM6/15/17
to Django users
I was able to resolve the issue.
In mixins.py, .get_object() was unresolvable so I inherited from SingleObjectMixin also I had to use the id to check equality.

from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from django.views.generic.detail import SingleObjectMixin

class UserAuthorMixin(LoginRequiredMixin, SingleObjectMixin):
    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated() and request.user.id is not self.get_object().author.user.id:
Reply all
Reply to author
Forward
0 new messages