Django Form in ListView, error on POST of Form

Sarius :

Im trying to implement a chat-function for my website. In order to do that, i followed the following tutorial: https://channels.readthedocs.io/en/latest/tutorial/

I've then changed the code a little bit in order to implement it. Until here, everything works just fine. Now I want to store the form-data inside of a database, and thats where the problem appears. But first my code:

urls.py:

    from django.urls import path
    from .views import ChatOverView

    urlpatterns = [
        path('<int:pk>/', ChatOverView.as_view(), name='chat-explicit'),
        path('', ChatOverView.as_view(), name='chat-home'),
    ]

views.py (theres much code here that is probably not needed for this question, but since i dont know what part of it i can ignore, im just posting the whole file-content):

from django.views.generic import ListView
from django.views.generic.edit import FormMixin, FormView
from django.db.models import Q
from django.urls import resolve
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404

from .models import Message
from .forms import MessageRegisterForm


class ChatOverView(ListView, FormMixin):
    model = Message
    template_name = 'chat/home-chat.html'
    form_class = MessageRegisterForm
    success_url = '/thanks/'

    def form_valid(self, form):
        form = self.get_form()
        if form.is_valid():
            data = form.cleaned_data
            return super().form_valid(form)

    def get_context_data(self, *args, **kwargs):
        context = super(ChatOverView, self).get_context_data(*args, **kwargs)

        messages_raw = reversed(Message.objects.filter(Q(sender=self.request.user) | Q(receiver=self.request.user)))
        messages = {}

        for mes in messages_raw:
            # i am receiver
            if mes.sender != self.request.user:
                if mes.sender in messages:
                    messages[mes.sender].append({"received": mes})
                else:
                    messages.update({mes.sender: [{"received": mes}]})
            # i sent
            else:
                if mes.receiver in messages:
                    messages[mes.receiver].append({"sent": mes})
                else:
                    messages.update({mes.receiver: [{"sent": mes}]})

        active_user = self.get_active_chat(messages)
        chatroom_name = self.get_chatroom_name(active_user)
        context.update(messages_data=messages, active=active_user, roomname=chatroom_name)
        return context

    def get_chatroom_name(self, active_chat):
        # my convention
        ids = [active_chat.id, self.request.user.id]
        ids.sort()
        return str(ids[0]) + '_' + str(ids[1])

    def get_active_chat(self, messages):
        url_name = resolve(self.request.path_info).url_name
        if url_name == "chat-home":
            return list(messages.keys())[0]
        else:
            pk_user = self.request.build_absolute_uri().split("/")[-2]
            user = get_object_or_404(User, pk=pk_user)
            return user

home-chat.html:

{% extends "solawi/base.html" %}
{% load define_dictfilters %}
{% block content %}
            <form class="bg-light" method="post">
                <div class="input-group">
                    {% csrf_token %}
                    {{ form }}
                    <div class="input-group-append">
                        <button type="submit" id="chat-message-submit" value="enter">send</button>
                    </div>
                </div>
            </form>    
{% endblock content %}

models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User


class Message(models.Model):
    sender = models.ForeignKey(User, related_name="sender", on_delete=models.CASCADE)
    receiver = models.ForeignKey(User, related_name="receiver", on_delete=models.CASCADE)
    content = models.TextField()
    date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.sender.username + ' to ' + self.receiver.username

The rest of the files/settings entrys are the same as in the tutorial linked above.

Now comes the problem: when submitting the form, i get the following error: Method Not Allowed (POST): /chat/ Method Not Allowed: /chat/ HTTP POST /chat/ 405 [0.00, 127.0.0.1:54424]

How can i fix it? Thank you for your Help!!

Chris :

ListView implements a get() method, but no post() method. You need to implement a post() method in order for the view to allow POST requests.

You could subclass django.views.generic.ProcessFormView to get this, or, if you really need a ListView, then you can add a post() method to the class which handles the form validation and whatever else you need to do. Here is how ProcessFormView implements it:

    def post(self, request, *args, **kwargs):
        """
        Handle POST requests: instantiate a form instance with the passed
        POST variables and then check if it's valid.
        """
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=25596&siteId=1