基于类视图下,如何将评论作者默认设为当前登录用户?
问题:基于类的视图中自动设置评论作者为当前登录用户
我需要实现提交评论时,将评论的作者字段自动设置为当前登录用户,使用的是Django基于类的视图(Class Based Views)。尝试过多种方法但均未奏效,包括修改表单字段、在视图中设置form.instance.author或comment.author等。
现有代码
views.py
class CommentPost(SingleObjectMixin, FormView): model = Article form_class = CommentForm template_name = "article_detail.html" def post(self, request, *args, **kwargs): self.object = self.get_object() return super().post(request, *args, **kwargs) def form_valid(self, form): comment = form.save(commit=False) form.instance.author = self.request.user comment.article = self.object comment.save() return super().form_valid(form) def get_success_url(self): article = self.get_object() return reverse("article_detail", kwargs={"pk": article.pk})
models.py
class Comment(models.Model): article = models.ForeignKey(Article, on_delete=models.CASCADE) comment = models.CharField(max_length=140) author = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, ) def __str__(self): return self.comment def get_absolute_url(self): return reverse("article_list")
article_detail.html
<!-- templates/article_detail.html --> {% extends 'base.html' %} {% load crispy_forms_tags %} {% block content %} <body class="d-flex h-100"> <div class="container"> <div class="col-8 mx-auto"> <h3 class="pb-4 mb-4 fst-italic border-bottom">Article detail</h3> <div class="article-entry"> <h2>{{object.title}}</h2> <p class="text-black-50 fst-italic">by {{object.author}} | {{object.date}}</p> <p>{{object.body}}</p> </div> {% if user.is_authenticated and user == article.author or user.is_superuser %} <p> <button class="btn"> <a class="text-decoration-none text-white" href="{% url 'article_edit' article.pk %}">edit</a> </button> <button class="btn"> <a class="text-decoration-none text-white" href="{% url 'article_delete' article.pk %}">delete</a> </button> </p> {% endif %} <br/> {% if article.comment_set.all %} <hr/> <h5>Comments</h5> {% for comment in article.comment_set.all %} <p>{{ comment.author }} – {{ comment }}</p> {% endfor %} {% endif %} <br/> <hr/> <h5>Add a comment</h5> <form action="" method="post"> {% csrf_token %} {{ form|crispy }} <button class="btn" type="submit">Save</button> </form> <br/> <p>Back to <a href="{% url 'article_list' %}">all articles</a></p> </div> </div> </body> {% endblock content%}
forms.py
class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ("comment", "author")
解决方案
1. 修改表单,移除作者字段
不需要让用户手动选择作者,因此在forms.py中移除author字段:
class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ("comment",)
2. 修正视图中的form_valid方法
之前的代码同时操作了comment和form.instance,导致赋值冲突。直接对form.save(commit=False)返回的实例赋值即可:
def form_valid(self, form): comment = form.save(commit=False) comment.author = self.request.user # 直接给comment实例赋值作者 comment.article = self.object comment.save() return super().form_valid(form)
3. 强制用户登录才能提交评论(可选)
为了避免匿名用户提交评论导致self.request.user为匿名用户,给视图添加LoginRequiredMixin:
from django.contrib.auth.mixins import LoginRequiredMixin class CommentPost(LoginRequiredMixin, SingleObjectMixin, FormView): # 原有代码...
说明
- 移除表单中的
author字段后,页面上不会再显示作者选择框,避免用户输入覆盖后台自动赋值。 - 修正
form_valid方法后,确保评论实例的作者被正确设置为当前登录用户。 - 添加
LoginRequiredMixin可确保只有登录用户才能访问评论提交功能,避免出现匿名用户提交时的错误。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

