Djangoを使用してブログサイトを開発しています。私のサイトでは、ユーザーが私のブログ投稿にコメントしたり、お互いに返信したりできるようになり、「スレッドコメント」構造を使用して表示されます(ユーザー機能はまだ開始していません。コメントのみです)。 Django-mpttを使用してスレッド化されたコメントが正しく機能するようになっていますが(少なくとも今のところ)、実行しているルートまたは手順が正しい方向にあるかどうかはわかりません。私が経験したほとんどすべてのチュートリアルは、コメントに関しては表面的なものにすぎず、Djangoのスレッド化されたコメントについては説明していません。何が間違っているのか、何がもっとうまくできるのかについて、経験豊富な専門家のアドバイスが必要です。私が最後に望んでいるのは、何時間もの作業を行った後、はるかに受け入れられる方法があったことを見つけることです。
だから、これが私が明確にする必要があるもののリストです:
Django-mptt:
1つのHTMLページに複数のフォーム
これらが初心者の質問であり、私の投稿が長すぎる場合は申し訳ありません。初心者向けの現実的なソリューションを使用して、可能な限り最善の方法で物事をやりたいと思っています。フィードバックがあれば役に立ちます。ありがとうございました!これが私のブログアプリのコードです。
models.py
from Django.db import models
from mptt.models import MPTTModel, TreeForeignKey
class Post(models.Model):
"""Blog post"""
title = models.CharField(max_length=200)
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.body[:50] + '...'
class Comment(MPTTModel):
"""User comment"""
post = models.ForeignKey(Post, related_name='comments',on_delete=models.CASCADE)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children',db_index=True, on_delete=models.CASCADE)
user_comment = models.CharField(max_length=500, unique=True)
date_added = models.DateTimeField(auto_now_add=True)
# approved = models.BooleanField(default=False)
class MPTTMeta:
order_insertion_by = ['date_added']
def __str__(self):
return self.user_comment[:20]
なんらかの奇妙な理由で「そのような列がありません:承認されました」というエラーが表示されるため、「承認済み」はコメントアウトされています。
forms.py
from Django import forms
from .models import Post, Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['user_comment']
views.py
from Django.shortcuts import render
from Django.http import HttpResponseRedirect
from Django.urls import reverse
from .models import Post
from .forms import CommentForm
def posts(request):
"""Show all blog posts"""
posts = Post.objects.order_by('-date_added')
context = {
'posts': posts
}
return render(request, 'posts/posts.html', context)
def post(request, post_id):
"""Show single blog post"""
post = Post.objects.get(id=post_id)
comments = post.comments.all()
if request.method != 'POST':
comment_form = CommentForm()
else:
comment_form = CommentForm(data=request.POST)
try:
parent_id = request.POST['comment_id']
except:
pass
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.post = post
comment.parent = comments.get(id=parent_id)
comment.save()
return HttpResponseRedirect(reverse('posts:post', args=[post_id]))
context = {
'post': post,
'comment_form': comment_form,
'comments': comments,
}
return render(request, 'posts/post.html', context)
post.html
{% extends 'posts/base.html' %}
{% block blog_content %}
<h1>Post page!</h1>
<h3>{{ post.title }}</h3>
<h4>{{ post.date_added }}</h4>
<p>{{ post.body }}</p>
<form method="post" action="{% url 'posts:post' post.id %}">
{% csrf_token %}
{{ comment_form.as_p }}
<button type="submit">Add comment</button>
</form>
{% load mptt_tags %}
{% recursetree comments %}
<h5>{{ node.date_added }}</h5>
<p>{{ node.user_comment }}</p>
<form method="post" action="{% url 'posts:post' post.id %}">
{% csrf_token %}
{{ comment_form.as_p }}
<input type="hidden" name="comment_id" value="{{ node.id }}">
<button type="submit">Reply</button>
</form>
{% if not node.is_leaf_node %}
<div style="padding-left: 20px">
{{ children }}
</div>
{% endif %}
{% endrecursetree %}
{% endblock %}
urls.py
from Django.urls import path
from . import views
app_name = 'posts'
urlpatterns = [
path('posts/', views.posts, name='posts'),
path('posts/<int:post_id>/', views.post, name='post'),
]
MPTTツリーは、サブノードまたはノード数のリストを取得するのに最適です。これらはノードの追加/挿入にコストがかかり、コストは3つのサイズに比例して増加します。これらは、ツリーデータをリレーショナルデータベースに適合させるように設計されています。また、「書き込みよりも読み取りの方がはるかに多い」と騙されないでください。理想的には、ほとんどの読み取りは、その下のデータベースではなく、キャッシュにヒットする必要があります。
リレーショナルデータベースをスキップして、ツリーをネイティブに格納できるNoSQLデータベースを使用してみませんか? Djangoと、ほぼすべてのNoSQLデータベースを簡単に統合できます。