如何在模板中使用相应模型应用投票功能?

How to apply upvote functionality with corresponding Model in Template?

我正在 Django 中开发一个类似于 quora 的应用程序,但面临两个问题。我想,在问题详细视图中,如果用户没有对答案投赞成票,那么它将显示赞成票和总票数的选项。

这是我的 html 模板。

{% extends 'base.html' %}

{% block title %} {{ question.title }} {% endblock %}
{% block body %}
    <h3><i>{{ question.title }}</i></h3>
    {{ question.description }}
    {% for answer in question.answer_set.all %}
        <br>
        <div>
        <p>{{ answer.answer_text }} <span style="font-size: 15px">by [{{ answer.user }}]</span></p>
        <form method="post" action="{% url 'answer:detail' question.id %}">
            {% csrf_token %}
            <input type="hidden" name="type" value="vote">
            <input type="hidden" name="answer_id" value="{{ answer.id }}">
            {% for upvote in answer.upvote_set.all %}
                {% if upvote.user == request.user %}

                    <input type="submit" class="btn btn-sm btn-warning"
                           value="Downvote|{{ answer.upvote_set.all.count }}">
                {% else %}
                    {% if forloop.counter == 1 %}
                        <input type="submit" class="btn btn-success" value="Upvote|{{ answer.upvote_set.all.count }}">
                    {% endif %}
                {% endif %}
            {% empty %}
                <input type="submit" class="btn btn-sm btn-success" value="Upvote|{{ 0 }}">

            {% endfor %}
        </form>

    {% endfor %}

{% endblock %}

models.py

from django.contrib.auth.models import User
from django.db import models
from django.shortcuts import reverse


# Create your models here.

class Question(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=200, blank=True, null=True)
    description = models.TextField()
    pub_date = models.DateTimeField()

    def __str__(self):
        return self.title


class Answer(models.Model):
    answer_text = models.TextField()
    questions = models.ForeignKey(Question)
    pub_date = models.DateTimeField(auto_now_add=True)
    # upvote = models.IntegerField(null=True, blank=True)
    user = models.ForeignKey(User)

    def __str__(self):
        return self.answer_text

    def get_absolute_url(self):
        return reverse('answer:answer_by_me', kwargs={'pk': self.user.id})


class Upvote(models.Model):
    user = models.ForeignKey(User)
    answers = models.ForeignKey(Answer)

    def __str__(self):
        return self.user.username

如果用户和任何其他用户已经投票,它会同时显示赞成票和反对票按钮。 如果在 answer.upvote_set.all 中找到用户的投票,我不能使用 break 关键字,即使我不能使用像 if request.user in answer.upvote_set.all 这样的成员运算符,因为它 returns upvote 对象查询集。我该如何解决?

您必须为此创建一个 custom tag

在您的应用的 templatetags 文件夹中创建一个名为 upvote_tags.py 的文件。

from django import template

register = template.Library()

@register.simple_tag
def has_upvoted(user, answer):
    return user.id in list(answer.upvote_set.all().values_list("user", flat=True))

现在您可以在您的模板中使用它了。

# load tag at top of your html.
{% load upvote_tags %}

...
# remove your loop and use condition as below 
{% if has_upvoted request.user answer %}
   # show downvote button for this answer
{% else %}
   # show upvote button for this answer
{% endif %}

您还必须在 settings.py.

的 libraries 关键字下的 TEMPLATE 列表中输入您的标签文件
TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'libraries':{
               # make your file entry here.
               'upvote_tags': 'app_name.templatetags.upvote_tags',
            }
        },
    },
]