Django Добавление комментария к посту. Ошибка "Comment.username" must be a "User" instance
Хочу сделать так, чтобы залогиненный пользователь мог оставлять комментарии к постам. Знаю, что ошибка в PostDetailView, но не получается исправить. Объясните пожалуйста, что я делаю не так.
class PostDetailView(DetailView):
model = Post
template_name = 'base/post_detail.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs["pk"]
post = get_object_or_404(Post, pk=pk)
comments = post.comment_set.all().filter(active=True)
context['comments'] = comments
context['form'] = CommentForm()
return context
def post(self, request, *args, **kwargs):
form = CommentForm(request.POST)
self.object = self.get_object()
context = super().get_context_data(**kwargs)
post = Post.objects.filter(id=self.kwargs['pk'])[0]
comments = post.comment_set.all()
username = self.request.user.username
context['post'] = post
context['username'] = username
context['comments'] = comments
context['form'] = form
if form.is_valid():
content = form.cleaned_data['content']
comment = Comment.objects.create(
username=username, content=content, post=post
)
form = CommentForm()
context['form'] = form
return self.render_to_response(context=context)
return self.render_to_response(context=context)
models:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self) -> str:
return f'{self.author}: {self.title}'
def get_absolute_url(self):
return reverse("base:post-detail", kwargs={"pk": self.pk})
class Meta:
ordering = ['-date_posted']
indexes = [
models.Index(fields=['-date_posted'])
]
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
username = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ['created']
indexes = [
models.Index(fields=['created'])
]
def __str__(self) -> str:
return f'Comment by {self.username} on {self.post}'
forms:
from .models import Comment
from django import forms
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['content']
post_detail.html:
{% extends "base/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src='{{ object.author.profile.image.url }}'>
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"F d, Y" }}</small>
{% if object.author == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url "base:post-update" object.id %}">Update</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url "base:post-delete" object.id %}">Delete</a>
</div>
{% endif %}
</div>
<h2 class="article-title">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
<!-- Form to leave comment -->
<div class="row mt-5">
<div class="col-lg-6 offset-lg-3">
<h3>Leave a comment</h3>
<form method='POST'>
{% csrf_token %}
<div class="form-group">
<span class="ml-2"></span>{{ form.content.label_tag }}
<textarea class="form-control {% if form.content.errors %}is-invalid{% endif %}" id="id_content"
name="content" rows="4">{{ form.content.value|default:'' }}</textarea>
</div>
<button class="btn btn-primary ml-2" type="submit">Reply</button>
</form>
</div>
</div>
</div>
<!-- List of comments -->
{% if comments %}
<div class="row mt-5">
<div class="col-lg-6 offset-lg-3">
Comment{{ comments.count|pluralize }}
<span class="badge badge-dark ml-2">{{ comments.count }}</span>
</div>
{% for comment in comments %}
<div class="col-lg-6 offset-lg-3 mt-2">
<div class="card p-2">
<div class="row">
<div class="col-12">
<img class="rounded-circle article-img" src='{{ object.author.profile.image.url }}'>
<strong>{{ comment.username }}</strong>
</div>
<div class="col-12">
<p class="m-1 mt-3">{{ comment.content }}</p>
<p class="text-right text-muted"><small>{{ comment.created }}</small></p>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock content %}
Ответы (2 шт):
Автор решения: randomly
→ Ссылка
Попробуй импортировать модуль User от сюда
from django.contrib.auth.models import User
и вместо
username=username
используй
username=User
в итоге должно получиться что-то подобное:
if form.is_valid():
content = form.cleaned_data['content']
comment = Comment.objects.create(
username=User, content=content, post=post
)
form = CommentForm()
context['form'] = form
return self.render_to_response(context=context)
return self.render_to_response(context=context)
Я попробовал именно такой метод, так ка сам Django ругается на не использование User
Автор решения: Gaas Maxim
→ Ссылка
По итогу надо было убрать:
username = self.request.user.username context['username'] = username
и заменить там на:
comment = Comment.objects.create( username=request.user, content=content, post=post )
class PostDetailView(DetailView):
model = Post
template_name = 'base/post_detail.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs["pk"]
post = get_object_or_404(Post, pk=pk)
comments = post.comment_set.all().filter(active=True)
context['comments'] = comments
context['form'] = CommentForm()
return context
def post(self, request, *args, **kwargs):
form = CommentForm(request.POST)
self.object = self.get_object()
context = super().get_context_data(**kwargs)
post = Post.objects.filter(id=self.kwargs['pk'])[0]
comments = post.comment_set.all()
context['post'] = post
context['comments'] = comments
context['form'] = form
if form.is_valid():
content = form.cleaned_data['content']
comment = Comment.objects.create(
username=request.user, content=content, post=post
)
form = CommentForm()
context['form'] = form
return self.render_to_response(context=context)
return self.render_to_response(context=context)

