diff --git a/pinax/messages/mixins.py b/pinax/messages/mixins.py new file mode 100644 index 0000000..c1280c3 --- /dev/null +++ b/pinax/messages/mixins.py @@ -0,0 +1,11 @@ +from django.contrib.auth.mixins import LoginRequiredMixin + + +class PinaxMessageBaseAuthMixin(LoginRequiredMixin): + """ + This mixin is a replacement for the login_required decorator used. + Pinax Messages uses as a base to apply possible common functionalities + across views in the project and to make the code consistent and + maintainable. + """ + pass diff --git a/pinax/messages/models.py b/pinax/messages/models.py index 70e3037..a1a9afa 100644 --- a/pinax/messages/models.py +++ b/pinax/messages/models.py @@ -39,6 +39,26 @@ def get_absolute_url(self): def first_message(self): return self.messages.all()[0] + def earliest_message(self, user_to_exclude=None): + """ + :param user_to_exclude: Exclude the messages from a given user + Returns the earliest message sent + """ + try: + return self.messages.exclude(sender=user_to_exclude).earliest('sent_at') + except Message.DoesNotExist: + return + + def last_message(self, user_to_exclude=None): + """ + :param user_to_exclude: Exclude the messages from a given user + Returns the earliest message of the thread + """ + try: + return self.messages.exclude(sender=user_to_exclude).latest('sent_at') + except Message.DoesNotExist: + return + @property @cached_attribute def latest_message(self): diff --git a/pinax/messages/views.py b/pinax/messages/views.py index 1df2116..ccd0c13 100644 --- a/pinax/messages/views.py +++ b/pinax/messages/views.py @@ -1,6 +1,5 @@ from django.http import HttpResponseRedirect from django.urls import reverse_lazy -from django.utils.decorators import method_decorator from django.views.generic import ( CreateView, DeleteView, @@ -10,23 +9,15 @@ from .forms import MessageReplyForm, NewMessageForm, NewMessageFormMultiple from .models import Thread +from .mixins import PinaxMessageBaseAuthMixin -try: - from account.decorators import login_required -except: # noqa - from django.contrib.auth.decorators import login_required - -class InboxView(TemplateView): +class InboxView(PinaxMessageBaseAuthMixin, TemplateView): """ View inbox thread list. """ template_name = "pinax/messages/inbox.html" - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super().dispatch(*args, **kwargs) - def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) if self.kwargs.get("deleted", None): @@ -44,7 +35,7 @@ def get_context_data(self, **kwargs): return context -class ThreadView(UpdateView): +class ThreadView(PinaxMessageBaseAuthMixin, UpdateView): """ View a single Thread or POST a reply. """ @@ -54,10 +45,6 @@ class ThreadView(UpdateView): template_name = "pinax/messages/thread_detail.html" success_url = reverse_lazy("pinax_messages:inbox") - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super().dispatch(*args, **kwargs) - def get_queryset(self): qs = super().get_queryset() qs = qs.filter(userthread__user=self.request.user).distinct() @@ -77,16 +64,12 @@ def get(self, request, *args, **kwargs): return response -class MessageCreateView(CreateView): +class MessageCreateView(PinaxMessageBaseAuthMixin, CreateView): """ Create a new thread message. """ template_name = "pinax/messages/message_create.html" - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super().dispatch(*args, **kwargs) - def get_form_class(self): if self.form_class is None: if self.kwargs.get("multiple", False): @@ -111,7 +94,7 @@ def get_form_kwargs(self): return kwargs -class ThreadDeleteView(DeleteView): +class ThreadDeleteView(PinaxMessageBaseAuthMixin, DeleteView): """ Delete a thread. """ @@ -119,10 +102,6 @@ class ThreadDeleteView(DeleteView): success_url = reverse_lazy("pinax_messages:inbox") template_name = "pinax/messages/thread_confirm_delete.html" - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super().dispatch(*args, **kwargs) - def delete(self, request, *args, **kwargs): self.object = self.get_object() success_url = self.get_success_url()