L
L
LeMar2020-05-28 06:10:20
Django
LeMar, 2020-05-28 06:10:20

How to send the comment's parent to the database when submitting a comment?

I am making a news portal. It came down to the implementation of comments. Decided to use django-mptt. I did everything according to the instructions, it seemed to work. But at that time I had only one article. As soon as I added a few more, I noticed that the same comments are shown in all articles (There was no binding of comments to the article). The mptt instruction contained the following:
def show_genres(request):
return render(request, "genres.html", {'genres': Genre.objects.all()})
And I have repeated the context - 'news': News .objects.all(). And in all articles all comments were shown.

I decided to do it differently - before saving the form, attach a comment to the article.
Here are the views :

def news_detail(request, slug, pk):
    detail_news = get_object_or_404(News, slug__iexact=slug)

  if request.method == "POST":
        form = CommentForm(request.POST or None)
        if form.is_valid():

            form = form.save(commit=False)
            if request.POST.get("news_parent",None):
                form.news_parent_id = int(request.POST.get("news_parent"))
                #if request.POST.get("parent",None):
                    #form.parent_id = int(request.POST.get("parent"))
            #form.parent_id = node.parent_id
            form.news_parent_id = pk
            form.user = request.user
            form.save()
            return HttpResponseRedirect(request.path)

    else:
        form = CommentForm()
    return render(request, 'news/news_detail.html', context={"detail_news": detail_news,"comments": Comment.objects.filter(news_parent_id=detail_news), 'form': form})


I made a link to the article, it works. But MPTT stopped working correctly. When replying to a comment, the Parent of the comment is not passed to the database.
I tried to make a binding by analogy with a binding to an article, but it doesn’t work (there is commented code in views).

How can I make it so that when submitting the form (reply comment), the Parent of the comment is passed and the response comment works normally?

Full views:

from django.shortcuts import render, get_object_or_404, redirect
from news.models import News, Comment
from news.forms import CommentForm
from django.http import HttpResponse, HttpResponseRedirect
# Create your views here.

def news_list(request):
    news = News.objects.all()
    return render(request, 'news/news_list.html', context={"news": news})


def news_detail(request, slug, pk):
    detail_news = get_object_or_404(News, slug__iexact=slug)
   # comment = Comment.objects.filter(news=detail_news)
    #for object in comment:
     #   object.save()
    if request.method == "POST":
        form = CommentForm(request.POST or None)
        if form.is_valid():

            form = form.save(commit=False)
            if request.POST.get("news_parent",None):
                form.news_parent_id = int(request.POST.get("news_parent"))
                if request.POST.get("parent",None):
                    form.parent_id = int(request.POST.get("parent"))
            #form.parent_id = node.parent_id
            form.news_parent_id = pk
            form.user = request.user
            form.save()
            return HttpResponseRedirect(request.path)

    else:
        form = CommentForm()
    return render(request, 'news/news_detail.html', context={"detail_news": detail_news,"comments": Comment.objects.filter(news_parent_id=detail_news), 'form': form})


Models.py:

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
from ckeditor_uploader.fields import RichTextUploadingField
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.

class News (models.Model):
    user = models.ForeignKey(User,verbose_name="Автор", on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    preview = models.CharField(max_length=200)
    text_news = RichTextUploadingField()
    image_news = models.ImageField(upload_to='static/img/news_list/', height_field='img_height', width_field='img_width', max_length=100)
    img_width = models.PositiveIntegerField(null=True)
    img_height = models.PositiveIntegerField(null=True)
    date_news = models.DateField(auto_now=True, null=True)
    slug = models.SlugField(max_length=255, unique=True)

    def get_absolute_url(self):
        return reverse('news_detail_url', kwargs={'slug': self.slug})

    def __str__(self):
        return str(self.title)


class Comment(MPTTModel):
    user = models.ForeignKey(User, verbose_name="Пользователь", on_delete=models.CASCADE, null=True)
    text = models.CharField(max_length=1000, unique=True)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
    time_comment = models.DateTimeField (auto_now=True, null=True)
    news_parent = models.ForeignKey(News, on_delete=models.CASCADE, null=True)

    class MPTTMeta:
        order_insertion_by = ['user']


Sample:

<!DOCTYPE html>
{% extends 'base.html' %}
{% load mptt_tags %}
{% load static %}
<html lang="en">
<head>
    {% block head %}
    <meta charset="UTF-8">
    <title>Новость</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/news.css' %}">
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
   <script src="{% static 'js/news.js' %}"></script>
    {% endblock %}
</head>
<br>

{% block content %}
<div>
    <h2 class="title">{{ detail_news.title }}</h2>

    <p class="preview">{{ detail_news.preview }}</p>
    {% autoescape off %}
    <div class="text_news">{{ detail_news.text_news }}</div>
    {% endautoescape %}
    <p class="date_news">{{ detail_news.date_news }}</p>
</div>

{% comment %}
    {% for comment in comments %}
    Пользователь - {{ comment.user }}</br>
    {{ comment.text }}</br>
    <a href="#formReview" onclick="addReview('{{ comment.user }}', '{{ comment.id }}')">Ответить</a></br></br>
        {% if comment.parent %}
                {% for comment_answer in comment_answers %}
                    Пользователь2 - {{ comment_answer.user }}</br>
                    {{ comment_answer.text }}</br></br>
                {% endfor %}
        {% endif %}
    {% empty %}
        <p>Нет комментариев</p>
    {% endfor %}
{% endcomment %}

<div class="comments">
    <p class="title_comment">Комментарии</p>
    {% recursetree comments %}
        <li>
            <p>{{ node.user }}</p>
            <p class="time_comment">{{ node.time_comment }}</p>
            <p>{{ node.text }}</p>
            {% if user.is_active %}
            <a href="#formReview" onclick="addReview('{{ node.user }}', '{{ node.id }}')">Ответить</a></br></br>
            {% endif %}
            {% if not node.is_leaf_node %}
                <ul class="children">
                    {{ children }}
                </ul>
            {% endif %}
        </li>
    {% endrecursetree %}
</ul>



    {% if user.is_active %}
        <form action="" method="post" id="formReview">
            {% csrf_token %}
             <input type="hidden" name="news_parent" id="contactparent" value="">

            <p>Комментарий: </p>
            <textarea type="text" name="text" maxlength="100"  id="contactcomment"></textarea><label for="contactcomment"></label>

            <button type="submit">Отправить</button>
        </form>
    {% else %}
        <h4>Что бы оставить комментарий <a href="#modal1" class="open_modal">авторизуйтесь</a></h4>
    {% endif %}
</div>
</div>

    <script>
        function addReview(user, id) {
            document.getElementById("contactparent").value = id;
            document.getElementById("contactcomment").innerText = `${user}, `
        }
    </script>
{% endblock %}

</body>
</html>


Main URLS:

from django.contrib import admin
from django.urls import path, include
from django.conf.urls import url
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('news.urls')),
    url(r'^accounts/', include('allauth.urls')),
    #path (r'^comments/', include('news.urls')),
    path('ckeditor/', include('ckeditor_uploader.urls')),
]

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
noremorse_ru, 2020-05-28
@noremorse_ru

Well, you don’t have the parent field in the form)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question