Django Модель и форма для системы комментариев
Я сделал систему комментариев под моими книгами, где только авторизованный пользователь может комментировать. Когда я использую форму для добавления комментария, она не работает! Почему?
вот мои модели
models.py
class Books(models.Model):
author = models.ManyToManyField(Authors)
title = models.CharField(max_length=250)
number_of_pages = models.PositiveIntegerField(validators=[MaxValueValidator(99999999999)])
date_added = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
publication_date = models.PositiveIntegerField(default=current_year(), validators=[MinValueValidator(300),
max_value_current_year])
cover = models.ImageField(upload_to='pics/covers/', default='pics/default-cover.jpg')
pdf_file = models.FileField(upload_to='pdfs/books/', default='pdfs/default-pdf.pdf')
category = models.ForeignKey(Categories, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Comments(models.Model):
book = models.ForeignKey(Books, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{} - {}'.format(self.livre.title, self.user)
вот мои формы
forms.py
class BookForm(ModelForm):
class Meta:
model = Books
fields = '__all__'
class CommentForm(ModelForm):
class Meta:
model = Comments
fields = ['body']
вот мои взгляды
views.py
@login_required(login_url='login')
def book_detail_view(request, book_id):
books = get_object_or_404(Books, pk=book_id)
context = {'books': books,}
return render(request, 'book_detail.html', context)
@login_required(login_url='login')
def add_comment(request, comment_id):
form = CommentForm()
books = get_object_or_404(Books, pk=comment_id)
user = request.user
if request.method == "POST":
form = CommentForm(request.POST, instance=books)
if form.is_valid():
comment = form.save(commit=False)
comment.user = user
comment.books = books
comment.save()
return redirect('book_detail', books.id)
context = {'form': form}
return render(request, 'comment_form.html', context)
Здесь страница подробностей моей книги
book_detail.html
{% extends 'base.html' %}
{% block title %} {{ books.title }} {% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-4">
<p><img src="{{ books.cover.url }}"></p>
</div>
<div class="col-lg-8">
<h2>{{ books.title }}</h2>
<b>Author : </b>
{% for author in books.author.all %}
<a href="{% url 'detail_author' author.id %}">{{ author.name }}</a>
{% if not forloop.last %},{% endif %}
{% endfor %}<br/>
<b>Catégory : </b>{{ books.category }}<br/>
<b>Pages : </b>{{ books.number_of_pages }}<br/>
<b>Publication : </b>{{ books.publication_date }}<br/>
<b>Date added : </b>{{ books.date_added }}<br/>
<b>Updated : </b>{{ books.updated }}<br/>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<p><a href="{{ books.pdf_file.url }}"><button class="btn btn-outline-dark btn-sm"><i class="far fa-eye"></i> Read</button></a></p>
</div>
</div>
<hr/>
<div class="container-fluid">
<h2>Comments</h2>
</div>
<div class="container-fluid">
{% if not books.comments.all %}
<p>No comments yet ! <a class="text-primary" href="{% url 'add_comment' books.id %}">Add comment...</a></p>
{% else %}
<a class="text-primary" href="{% url 'add_comment' books.id %}">Add comment !</a><br/><br/>
{% for comment in books.comments.all%}
<b>{{ comment.user }}</b> - <span class="text-muted" style="font-size: 13px;">{{ comment.date }}</span>
<p>{{ comment.body }}</p>
{% endfor %}
{% endif %}
</div>
{% endblock %}
вот моя форма для модели комментария
comment_form.html
{% extends 'base.html' %}
{% block title %} Add a comment {% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Add this comment</button>
</form>
{% endblock %}
вот мои урлы
urls.py
urlpatterns = [
# BOOKS
path('book/<int:book_id>/', views.book_detail_view, name='book_detail'),
# COMMENTS
path('book/<int:comment_id>/comment/', views.add_comment, name='add_comment'),
]
Ваша форма в настоящее время настроена на редактирование книги, а не комментария, вам следует убрать instance=books
:
if request.method == "POST":
# no instance=books ↓
form = CommentForm(request.POST)
Если вы используете instance=books
, форма установит атрибуты объекта Books
, а затем comment = form.save(commit=False)
приведет к тому, что comment
станет объектом Books
, который уже сохранен и, следовательно, обновлен в базе данных.
Вы также допустили опечатку при установке book
объекта Comments
: это book
, а не :books
if form.is_valid():
comment = form.save(commit=False)
comment.user = user
comment.book = books # ← .book, not .books
comment.save()
Примечание: обычно модели Django дается сингулярное имя, поэтому
Book
вместо.Books