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.

Вернуться на верх