【问题标题】:django forms - how to update user data from previous comment when user posts a new commentdjango forms - 当用户发表新评论时如何从以前的评论中更新用户数据
【发布时间】:2023-03-17 04:34:01
【问题描述】:

我觉得我真的很接近了,但还不是很接近。请多多包涵,因为我还处于学习 django 的初级阶段。

我有一个功能,用户可以对每篇博文发表评论。我想在他的名字旁边显示每个用户拥有的 cmets 总数。如果该用户在 4 个不同的帖子上留下了 4 个 cmets,我希望它在我网站上的每个个人 cmets 上的他的名字旁边显示“4 个 cmets”。

我已经制作了一个模型方法,我把它放在我的视图中,它会自动更新每个用户的总 cmets。唯一的问题是,如果用户留下了两个 cmets,则只有他的最新评论会显示“2 total cmets”。他的前一个只显示“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 %}

用户 cmets 一次 = FirstName LastName 1。 用户 cets 两次,他的第二条评论 = FirstName LastName 2,但第一条评论保持不变。

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

【问题讨论】:

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


    【解决方案1】:

    首先,我认为您不需要 review_count 作为数据库字段。除非你打算用它来排序(或做一些需要它在数据库中的事情)。

    从您的问题“django forms - how to update user data from previous comment when user post a new comment”我相信您知道它为什么不起作用。

    因为是之前的评论,更新最新评论的数据不会自动更新之前的cmets(如果默认情况下会是灾难性的:-))

    无论如何,一旦您删除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? 
    

    如果不需要是数据库字段,则不需要。您可以轻松地将其设为计算属性并将其缓存(如果您觉得每次都重新计算代价高昂,并且您并不真正关心数据的“新鲜度”)。

    顺便说一句,如果您需要更新旧的 cmets(您最初想要的方式),您会像这样进行批量更新

    我在这里过于冗长:

    comments = Comment.objects.filter(user_id=self.user.id)
    count = comments.count()
    comments.update(review_count=count)
    

    这将更新与过滤器参数匹配的所有 cmets。但就像我说的,我认为这不是你想做的最好的方法。

    阅读

    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

    【讨论】:

    • 感谢您的输入和链接,我已经查看了它们并找到了解决方案!您的代码在顶部有点偏离,而不是“return self.usernamee.count()”,这给了我一个错误,我使用了“return self.user.comment_set.count”,它有效!
    • 是的,如果评论直接与UserProfile 模型相关,它会起作用,但您也可以使用self.user.usernamee.count()(这就是related_name 用于comment_set 的默认相关如果您不指定任何名称,则为名称)
    • 请随时将我的答案标记为正确。因为它解决了你的问题:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多