Search code examples
djangodjango-modelsdjango-viewsdjango-channels

Save chat thread only if user sends a message


I'm using Django Channels 2.1.2 with my Django 2 project and need some assistance in configuring the thread to only be saved if a user actually sends a message.

Right now, if a user clicks on chat, they go to the chat message page and the thread is created and saved in their inbox.

Even if they decide to not end up messaging, the empty chat is still visible in both users inboxes.

The thread needs to be saved only after either user has sent a message.

Would someone mind helping me with this as I'm not sure what to do? I assume this line somehow needs to be modified obj, created = Thread.objects.get_or_new(self.request.user, other_username)

views.py

class InboxView(LoginRequiredMixin, ListView):
    template_name = 'chat/inbox.html'
    context_object_name = 'threads'
    def get_queryset(self):
        return Thread.objects.by_user(self.request.user).order_by('-timestamp')
        # by_user(self.request.user)

class ThreadView(LoginRequiredMixin, FormMixin, DetailView):
    template_name = 'chat/thread.html'
    form_class = ComposeForm
    success_url = '#'

    def get_queryset(self):
        return Thread.objects.by_user(self.request.user)

    def get_object(self):
        other_username  = self.kwargs.get("username")
        obj, created    = Thread.objects.get_or_new(self.request.user, other_username)
        if obj == None:
            raise Http404
        return obj

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = self.get_form()
        return context

    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseForbidden()
        self.object = self.get_object()
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        thread = self.get_object()
        user = self.request.user
        message = form.cleaned_data.get("message")
        ChatMessage.objects.create(user=user, thread=thread, message=message)
        return super().form_valid(form)

Solution

  • They are multiple ways of doing this:

    1. Modify your Thread View, so that it is usable without a Thread - maybe add the data that is required into your context, and then when a message is sent, use get_or_create
    2. The easier but lazier is to not have any Empty Threads show in your Inbox View - in your get_queryset, you can filter for Threads that only have messages within