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!