Делаю Новостной портал. Дело дошло до реализации комментариев. Решил использовать django-mptt. По инструкции всё сделал, вроде работало. Но на тот момент была у меня только одна статья. Как только добавил еще несколько, заметил, что одни и те же комментарии показываются во всех статьях (Не было привязки комментариев к статье). В инструкции mptt было следующее:
def show_genres(request):
return render(request, "genres.html", {'genres': Genre.objects.all()})
И я получается повторил по инструкции контекст - 'news': News.objects.all(). И во всех статьях показывались все комментарии.
Решил сделать по-другому - перед сохранением формы привязать комментарий к статье.
Вот 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})
Привязку к статье я сделал, работает. Но перестал правильно работать MPTT. При ответе на комментарий в базу данных не передается Родитель комментария.
Пытался сделать привязку по аналогии с привязкой к статье, но не получается (во views закомментированный код).
Как можно сделать, чтобы при отправке формы (ответного комментария) передавался Родитель комментария и нормально работал ответный комментарий?
Полный 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']
Шаблон:
<!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>
Главный 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')),
]