当前位置: 首页 > article >正文

如何检查列表中的某个帖子是否被当前用户投票

在 Django 项目中,如果需要检查一个列表中的某个帖子是否被当前用户投票(比如点赞或踩),可以通过数据库查询实现。以下是具体的实现方法,假设你使用的是 Django 并有如下的数据库模型结构:

在这里插入图片描述

问题背景

我正在创建一个reddit克隆,其中存在一个问题,我正在寻找一种方法来指示当前用户是否对某个特定问题进行过投票,而不会产生过多数据库请求。

我的模型如下:

class Thread(models.Model):
    title = models.CharField(max_length=200)
    text = models.TextField(max_length=max_post_length)
    created = models.DateField()
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    userUpVotes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='threadUpVotes')
    userDownVotes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='threadDownVotes')

    def __str__(self):
        return self.title


class Comment(MPTTModel):
    title = models.CharField(max_length=200)
    text = models.TextField(max_length=max_post_length)
    created = models.DateField()
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    thread = models.ForeignKey(Thread)
    parent = TreeForeignKey('self', related_name='children', blank=True, null=True)
    vote_count = models.IntegerField(default=0)
    userUpVotes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='commentUpVotes')
    userDownVotes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='commentDownVotes')

    class MPTTMeta:
        order_insertion_by = ['created']

    def save(self, *args, **kwargs):
        self.vote_count = self.userUpVotes.count() - self.userDownVotes.count()
        super(Comment, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

我的视图如下:

from django.shortcuts import get_object_or_404, render
from community.models import Thread, Comment
from django.http import HttpResponse


def detail(request, thread_id):
    thread = get_object_or_404(Thread, pk=thread_id)
    comments = thread.comment_set.all()

    return render(request, 'threads/detail.html', {
        'thread': thread,
        'comments': comments
    })

我的模板如下:

{% extends "base.html" %}
{% load mptt_tags %}
{% block content %}
    <h1>{{ thread.title }}</h1>
    <p>{{ thread.text }}</p>
    <ul class="comments">
        {% recursetree comments %}
            <li>
                <div class="comment-block clearfix">
                    <vote-up-down up="{{ node.up_vote_by_user }}"
                                  down="{{ node.user_down_vote }}"
                                  url="/community/comment/{{ node.id }}/vote/"
                                  count="{{ node.vote_count }}"></vote-up-down>
                    <div class="comment">
                        <h4>{{ node.title }}</h4>

                        <div class="text">{{ node.text }}</div>
                    </div>
                </div>
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>
{% endblock content %}

解决方案

对于这种问题,通常有两种解决方案:

1、通过模型方法

首先,我们需要在模型中添加两个方法,用来检查用户是否对某个节点进行过投票。

class Node(models.Model):
    ...

   def upvoted_by(self, user):
       return self.up_votes.filter(user=user).exists()

   def downvoted_by(self, user):
       return self.down_votes.filter(user=user).exists()

然后,在视图中,我们可以使用这些方法来检查用户是否对某个帖子进行过投票。

def detail(request, thread_id):
    thread = get_object_or_404(Thread, pk=thread_id)
    comments = thread.comment_set.all()

    for comment in comments:
        comment.up_voted_by_user = comment.upvoted_by(request.user)
        comment.down_voted_by_user = comment.downvoted_by(request.user)

    return render(request, 'threads/detail.html', {
        'thread': thread,
        'comments': comments
    })

最后,在模板中,我们可以使用这些变量来显示投票信息。

{% extends "base.html" %}
{% load mptt_tags %}
{% block content %}
    <h1>{{ thread.title }}</h1>
    <p>{{ thread.text }}</p>
    <ul class="comments">
        {% recursetree comments %}
            <li>
                <div class="comment-block clearfix">
                    <vote-up-down up="{{ node.up_voted_by_user }}"
                                  down="{{ node.down_voted_by_user }}"
                                  url="/community/comment/{{ node.id }}/vote/"
                                  count="{{ node.vote_count }}"></vote-up-down>
                    <div class="comment">
                        <h4>{{ node.title }}</h4>

                        <div class="text">{{ node.text }}</div>
                    </div>
                </div>
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>
{% endblock content %}

2、通过数据库查询

def detail(request, thread_id):
    thread = get_object_or_404(Thread, pk=thread_id)
    comments = thread.comment_set.all()

    upvoted_comments = request.user.comment_upvotes.filter(
        id__in=comments).values_list('pk', flat=True)

    downvoted_comments = request.user.comment_downvotes.filter(
        id__in=comments).exclude(
        id__in=upvoted_comments).values_list('pk', flat=True)

    return render(request, 'threads/detail.html', {
        'thread': thread,
        'comments': comments,
        'upvoted_comments': set(upvoted_comments),
        'downvoted_comments': set(downvoted_comments)
    })

最后,在模板中,我们可以使用这些变量来显示投票信息。

{% extends "base.html" %}
{% load mptt_tags %}
{% block content %}
    <h1>{{ thread.title }}</h1>
    <p>{{ thread.text }}</p>
    <ul class="comments">
        {% recursetree comments %}
            <li>
                <div class="comment-block clearfix">
                    <vote-up-down up="{%if node.pk in upvoted_comments %}{% endif %}"
                                  down="{%if node.pk in downvoted_comments %}{% endif %}"

  ...

通过上述方法,可以高效地检查列表中每个帖子是否被当前用户投票,并优化查询性能。


http://www.kler.cn/a/503261.html

相关文章:

  • 5、波分复用 WDM
  • WINFORM - DevExpress -> DevExpress总结[安装、案例]
  • android framework.jar 在应用中使用
  • Facebook 隐私变革之路:回顾与展望
  • 数据分析-使用Excel透视图/表分析禅道数据
  • 【数学】概率论与数理统计(五)
  • 无人设备遥控器之信号特性
  • gateway worker 分布式
  • C语言中NUL和NULL、‘\0‘之间的关系
  • R语言的数据库编程
  • spring学习( IOC【控制发转】)
  • 【Vim Masterclass 笔记13】第 7 章:Vim 核心操作之——文本对象与宏操作 + S07L28:Vim 文本对象
  • 1. Doris分布式环境搭建
  • 对受控组件和非受控组件的理解?应用场景?
  • 怎样在Linux PC上调试另一台PC的内核驱动程序,以及另一台Arm/Linux上的程序和驱动程序
  • Vue API 盲点解析
  • 针对服务器磁盘爆满,MySql数据库始终无法启动,怎么解决
  • CVPR 2024 3D方向总汇包含(3DGS、三维重建、深度补全、深度估计、全景定位、表面重建和特征匹配等)
  • PHP:构建高效Web应用的强大工具
  • 网络安全 | 人工智能在网络安全中的应用与挑战
  • 第一次作业三种方式安装mysql(Windows和linux下)作业
  • 安装Kubernetes,容器为containerd
  • 学习软件工程产品质量模型
  • R语言贝叶斯方法在生态环境领域中的高阶技术
  • C++基础篇——string 类型
  • 【C盘清理】C盘清理工具、Unity缓存文件转移