Как реализовать функциональность вывода комментариев под постом от имени авторизованного пользователя в Django?

Как правильно изменить код в файлах models.py, views.py и в шаблоне post_detail.html, чтобы комментарии, оставленные авторизованным пользователем, отображались на странице поста под его именем?  
<br/><br/>  
<b>models.py</b>  
<br/><br/>  
<pre><code class="python">from django.db import models


# Создайте свои модели здесь.
class Post(models.Model):
    title = models.CharField('Заголовок записи', max_length=50) 
    description = models.TextField('Текст записи', max_length=5000)
    date_add = models.DateTimeField('Дата публикации', auto_now=True)

    def __str__(self):
        return f'{self.date_add} / {self.title}'


class Comments(models.Model):
    name = models.CharField('Имя', max_length=16) # Нужно изменить, чтобы имя авторизованного пользователя записывалось здесь
    text_comments = models.TextField('Текст комментария', max_length=200)
    post = models.ForeignKey(Post, verbose_name='Публикация', on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.name} / {self.post}'</code></pre>  
<br/><br/>  
<b>views.py</b>  
<br/><br/>  
<pre><code class="python">class PostDetail(View):
    def get(self, request, post_id):
        post = Post.objects.get(id=post_id)
        return render(request, 'forum/post_detail.html', {'post': post})


class AddComments(View):
    def post(self, request, post_id):
        form = CommentsForm(request.POST)
        if form.is_valid():
            # comment_name = request.user.username
            # print(comment_name)
            comment = form.save(commit=False)
            comment.post_id = post_id
            comment.save()
            print(comment)
        return redirect('post_detail', post_id=post_id)</code></pre>  
  • 24 декабря 2024 г. 15:03
Ответы на вопрос 4
Для реализации функциональности вывода комментариев под постом от имени авторизованного пользователя в Django, вам нужно внести изменения в модели, представления и шаблоны. Давайте шаг за шагом изменим ваши файлы.

### 1. Изменения в models.py

Чтобы сохранять имя авторизованного пользователя в комментариях, вам нужно изменить модель `Comments`. Вместо поля `name`, которое сейчас является `CharField`, вы должны использовать `ForeignKey`, чтобы связать комментарий с пользователем (пользователь будет ссылаться на модель `User`):

```python
from django.contrib.auth.models import User

class Comments(models.Model):
    user = models.ForeignKey(User, verbose_name='Пользователь', on_delete=models.CASCADE)  # Изменение на ForeignKey к User
    text_comments = models.TextField('Текст комментария', max_length=200)
    post = models.ForeignKey(Post, verbose_name='Публикация', on_delete=models.CASCADE)
    
    def __str__(self):
        return f'{self.user.username} / {self.post}'
```

### 2. Изменения в views.py

В представлении `AddComments` вам нужно изменить код, чтобы устанавливать пользователя комментария:

```python
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

@method_decorator(login_required, name='dispatch')
class AddComments(View):
    def post(self, request, post_id):
        form = CommentsForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.user = request.user  # Устанавливаем текущего пользователя
            comment.post_id = post_id
            comment.save()
        return redirect('post_detail', post_id=post_id)
```

### 3. Изменения в посте detail шаблона post_detail.html

Теперь вам нужно отобразить комментарии, связанные с постом. Для этого вам нужно запросить комментарии в представлении `PostDetail` и передать их в шаблон:

```python
class PostDetail(View):
    def get(self, request, post_id):
        post = Post.objects.get(id=post_id)
        comments = Comments.objects.filter(post=post)  # Получаем комментарии для поста
        return render(request, 'forum/post_detail.html', {'post': post, 'comments': comments})
```

Теперь в вашем шаблоне `post_detail.html` вы можете отобразить комментарии следующим образом:

```html
<h1>{{ post.title }}</h1>
<p>{{ post.description }}</p>

<h2>Комментарии:</h2>
<ul>
    {% for comment in comments %}
        <li>{{ comment.user.username }}: {{ comment.text_comments }}</li>  <!-- Отображение имени пользователя и текста комментария -->
    {% empty %}
        <li>Комментариев нет.</li>
    {% endfor %}
</ul>

<form method="post" action="{% url 'add_comment' post.id %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Оставить комментарий</button>
</form>
```

### 4. Не забудьте проверить настройки

Убедитесь, что у вас есть соответствующая форма (`CommentsForm`) и что у вас настроены URL для добаления комментариев.

Эти изменения позволят вам сохранять и отображать комментарии под постом от имени авторизованного пользователя.
Добавьте в комментарий внешний ключ к модели юзера с возможностью оставить его пустым (как и name) 
При отрисовки формы ввода/сохранении коммента проверяйте, авторизирован ли пользователь. И в зависимости от этого выбирайте что записать.
В models.py username поменяйте на ForeignKey 
from django.contrib.auth.models import User

class Comments(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Пользователь')
    text_comments = models.TextField('Текст комментария', max_length=200)
    post = models.ForeignKey(Post, verbose_name='Публикация', on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.user.username} / {self.post}'

В form.py исключите name
class CommentsForm(forms.ModelForm):
    class Meta:
        model = Comments
        fields = ('text_comments',)

В views.py добавьте поле user
class AddComments(View):
    def post(self, request, post_id):
        form = CommentsForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post_id = post_id
            comment.user = request.user 
            comment.save()
        return redirect('post_detail', post_id=post_id)

В post_detail.html добавьте user.username
<div>
    <h3>Комментарии:</h3>
    <form action="{% url 'add_comments' post.id %}" method="post">
        <h3></h3>
        {% csrf_token %}
        <div>
            <textarea name="text_comments" placeholder="Ваш комментарий..."></textarea>
        </div>
        <div><input type="submit"></div>
    </form>
</div>
<div>
    {% for comment in post.comments_set.all reversed %}
    <div class="view-comment">
        <h4>{{ comment.user.username }}</h4>
        <p><i>{{ comment.text_comments }}</i></p>
    </div>
    {% endfor %}
</div>

Должно работать
А что, если через models.ForeignKey(User) попробовать? Или проверять, авторизован ли пользователь и из объекта user как раз username и записывать?
Похожие вопросы