django表单 - 当用户发布新评论时如何更新先前评论中的用户数据

时间:2017-09-06 00:45:09

标签: python django django-forms django-templates django-views

我觉得我真的很亲近,但还没到那里。请耐心等待我,因为在学习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,但第一条评论保持不变。

有关如何正确执行此操作的任何想法?非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

首先,我认为您不需要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/utils/#django.utils.functional.cached_property

https://docs.djangoproject.com/en/1.11/ref/models/querysets/#update

相关问题