我觉得自己真的很亲密,但还没有。请忍受我,因为我非常适合学习Django的初学者阶段。
我有一个功能,用户可以在其中对每个博客文章发表评论。我想显示每个用户名称旁边的评论总数。如果该用户在4个不同的帖子上留下了4个评论,我希望它在我的网站中的每个个人评论上都显示他的名字旁边的" 4个总注释"。
我制作了一种模型方法,该方法会自动更新每个用户的总注释。唯一的问题是,如果用户留下了两个评论,则只有他的最新评论将显示" 2个总注释"。他的前一个仅显示" 1"。
我的问题是,当用户留下新评论时,我该如何进行上一个条目更新?
models.py
class Comment(models.Model):
...
post = models.ForeignKey(Post, related_name="comments")
user = models.ForeignKey(User, related_name="usernamee")
email = models.EmailField(null=True, blank=True)
picture = models.TextField(max_length=1000)
...
review_count = models.IntegerField(default=0)
class UserProfile(models.Model):
...
def user_rating_count(self): #This is what adds "1" to the user's total post count
user_ratings =
Comment.objects.all().filter(user_id=self.user.id).count()
user_ratings += 1
return user_ratings
views.py
@login_required
def add_comment(request, slug):
post = get_object_or_404(Post, slug=slug)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.user = request.user
comment.email = request.user.email
comment.picture = request.user.profile.profile_image_url()
comment.review_count = request.user.profile.user_rating_count() #This is where I'd like it to update, but it doesn't seem to work this way
comment.save()
return redirect('blog:post_detail', slug=post.slug)
else:
form = CommentForm()
template = "blog/post/add_comment.html"
context = {
'form': form,
}
return render(request, template, context)
模板
{% for comment in post.comments.all %}
<p>{{ comment.user.first_name }} <b>{{ comment.user.last_name }}</b> {{ comment.review_count }}</p>
{% endfor %}
用户注释一次= firstName lastname 1。用户评论两次,他的第二个评论= firstName lastname 2,但第一个评论保持不变。
关于如何正确执行此操作的任何想法?任何帮助都非常感谢!
首先,我认为您不需要review_count
作为数据库字段。除了您计划使用它进行排序(或执行需要它在数据库中的某些事情)。
从您的问题" django表单 - 如何从上面的注释更新用户数据时当用户发布新评论时"我相信您对为什么不起作用有一个想法。
这是因为它是先前的评论,并且更新最新评论的数据不会自动更新以前的评论(默认情况下,这将是灾难性的:-))
无论如何,一旦您删除了review_count
并使user_rating_count
成为UserProfile
模型的属性,您的问题就会消失。
class UserProfile(models.Model):
@property
def user_rating_count(self):
"""This is what adds "1" to the user's total post count"""
return self.usernamee.count() # Remember the `related_name` you set earlier?
然后您可以在模板中使用它
{% for comment in post.comments.all %}
<p>{{ comment.user.first_name }} <b>{{ comment.user.last_name }}</b> {{ request.user.profile.user_rating_count }}</p>
{% endfor %}
如果您对每个页面上重新计算的值感到不安(应该是)。Django提供了一个漂亮的装饰器来缓存内存中的属性并减少数据库上的负载(当您重复调用方法/访问属性时)
from django.utils.functional import cached_property
class UserProfile(models.Model):
@cached_property
def user_rating_count(self):
"""This is what adds "1" to the user's total post count"""
return self.usernamee.count() # Remember the `related_name` you set earlier?
如果它不需要是数据库字段,则不需要。您可以轻松地将其作为计算的属性并缓存(如果您觉得每次重新计算它很昂贵,并且您并不真正在乎数据的"新鲜度")。
顺便说一句,如果您需要更新旧评论(最初想要的方式),您将完成像这样的批处理更新
我在这里冗长:
comments = Comment.objects.filter(user_id=self.user.id)
count = comments.count()
comments.update(review_count=count)
将更新与过滤器参数匹配的所有注释。但是就像我说的那样,我认为这不是您想做的最好的方法。
阅读
https://docs.djangoproject.com/en/1.11/ref/ref/utils/#django.utils.functional.cached_property
和
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#update