【问题标题】:Different display of items in view/template depending on model in Django视图/模板中项目的不同显示取决于 Django 中的模型
【发布时间】:2013-10-19 08:04:54
【问题描述】:

我有一个模型,看起来像这样:

class Topic(models.Model):
    name = models.CharField(max_length=50)

class Vote(models.Model):
    user = models.ForeignKey(User, related_name='user_set')
    topic = models.ForeignKey(Topic, related_name='topic_set')
    score = models.IntegerField(default=0)

    class Meta:
        unique_together = ("user", "topic")

在我的索引视图中,我想显示所有主题的列表。如果用户已经对该主题进行了投票,它应该显示他的分数。如果用户没有投票,它应该显示一个表单供用户投票。

我已经用这个方法扩展了模型作为Topic 类的一部分:

def user_has_already_voted(self, user):
    if not Vote.objects.filter(topic=self.id,user=user.id):
        return True
    else:
        return False

但是我不知道这是否是 Django 的方式,因为我不知道如何使用相应的模板编写视图来执行此任务。截至目前,我使用的是通用的IndexView,如下所示:

class IndexView(generic.ListView):
    template_name = 'topics/index.html'
    context_object_name = 'latest_topic_list'

    def get_queryset(self):
        return Topic.objects.order_by('-pub_date')[:5]

【问题讨论】:

    标签: python django templates


    【解决方案1】:

    使用上下文。在视图中添加:

        def get_context_data(self, **kwargs):
            context = {
                'is_voted' : self.user_has_already_voted(self.request.user),
            }
            context.update(kwargs)
            return super(IndexView, self).get_context_data(**context)
    

    在模板使用中:

    {% if is_voted %}
         Show vote results
    {% else %}
         Show vote form
    {% endif %}
    

    【讨论】:

    • 这看起来是一种很酷的方式来做这样的事情。是否可以更改查询集中每个对象的上下文,或者整个视图的上下文是否相同?
    【解决方案2】:

    您可以在模板中访问您的 user_has_already_voted:

    {% if topic.user_has_already_voted %}
    Show vote results
    {% else %}
    Show vote form
    {% endif %}
    

    【讨论】:

    • 对此我不确定。该方法需要一个用户作为参数,但据我所知,不能将参数传递给模板中的函数。 (或者至少没那么容易)
    【解决方案3】:

    您可以使用RedirectView 来实现:

    在你的views.py中,做这样的事情(这是我在当前项目中使用的代码,想法很相似。

    class AbstimmungRedirectView(generic.RedirectView):
    
        def get_redirect_url(self, pk):
            abstimmung = get_object_or_404(Abstimmung, pk=pk)     
            if abstimmung.abgeschlossen(): 
                #Die Abstimmung wurde durch Angabe eines Enddatms als "Beendet" markiert
                return reverse('my_app:MultipleChoiceFrageResults', args=(int(pk),))
            else:
                return reverse('my_app:MultipleChoiceFrageDetail', args=(int(pk),))
    

    您应该用您的has_voted() 替换我的abstimmung.abgeschlossen(),并为您要显示的模板使用反向网址。

    【讨论】:

      猜你喜欢
      • 2017-02-15
      • 2020-02-02
      • 2020-05-21
      • 2021-02-14
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多