如何向django QuerySet的每个条目添加一些上下文 [英] How to add some context to each entry of a django QuerySet

查看:125
本文介绍了如何向django QuerySet的每个条目添加一些上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Django 1.8.4与Python 3.4



我有一个比赛模型,定义一个方法,如果禁止订阅,则返回一个字符串。 >

  class Tournament(models.Model):
name = models.CharField(max_length = 200,null = True,blank = True )
subscriptions = models.ManyToManyField('ap_users.Profile')
is_subscription_open = models.BooleanField(default = True)
#...

def why_subscription_impossible自我请求):
如果没有request.user.profile.is_profile_complete():
返回'您的个人资料不完整'
elif不self.is_subscription_open:
返回'订阅被关闭'
elif< another_condition> ;:
return'另一个错误消息'

返回无

我想使用一般的ListView显示锦标赛的列表,我想使用修改显示方式的方法:

 < table class =table> 
< thead>
< td> Tournament< / td>
< td>订阅< / td>
< / thead>
{%in tournament_list%}
< tr>
< td> {{tournament.name}}< / td>
< td>
{%if tournament.why_subscription_impossible%}
{{tournament.why_subscription_impossible}}
{%else%}
< a href ={%url'ap_tournament:subscribe' tournament.id%}>订阅< / a>
{%endif%}
< / td>
< / tr>
{%endfor%}
< / table>

该视图是继承自 generic.ListView

  class IndexView(generic.ListView):
template_name ='ap_tournament / index.html '

def get_queryset(self):
return Tournament.objects.all()

显示的解决方案不起作用,因为我需要传递当前请求,以获取有关日志用户的信息。所以我试图将方法的结果添加到视图中的上下文

  class IndexView(generic.ListView):
template_name ='ap_tournament / index.html'

def get_queryset(self):
return Tournament.objects.all()

def get_context_data(self, ** kwargs)
context = super(IndexView,self).get_context_data(** kwargs)

additional_ctx_info = []
为self.get_queryset()中的比赛:
additional_ctx_info.append({
'reason_to_not_subscribe':tournament.why_subscription_impossible(self.request)
})

上下文['subscr_info'] = additional_ctx_info
返回上下文

显然,这也不行。我不知道如何使用n在tournament_list中的当前索引访问 subscr_info [n] 。我知道 forloop.counter0 来获取索引,但是我不能在模板中使用它(或者我不知道如何)。我试过:




  • {{subscr_info.forloop.counter0.reason_to_not_subscribe}} / li>
  • {{subscr_info。{{forloop.counter0}}。reason_to_not_subscribe}}



我还尝试在get_queryset()视图方法中注释QuerySet,并阅读有关aggregate()的信息,但我觉得仅在数据库支持的操作(AVG,COUNT,MAX,等等)。



我也觉得使用过滤器或模板标签在我的情况下不起作用,因为我需要使用方法的结果在code>如果标签。



有没有更好的解决方案或完全不同的方法来实现我想要的?

解决方案

在您看来,您还可以:

  tournaments = self.get_queryset()
在比赛中的比赛:
tournament.reason_to_not_subscribe = tournament.why_subscription_impossible(self.request)

然后在上下文中添加 tournaments


I use Django 1.8.4 with Python 3.4

I have a model for tournaments that defines a method which returns a string if a subscription is forbidden.

class Tournament(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    subscriptions = models.ManyToManyField('ap_users.Profile')
    is_subscription_open = models.BooleanField(default=True)
    # ...

    def why_subscription_impossible(self, request):
        if not request.user.profile.is_profile_complete():
            return 'Your profile is not complete'
        elif not self.is_subscription_open:
            return 'Subscriptions are closed'
        elif <another_condition>:
            return 'Another error message'

        return None

I want to display the list of tournaments, using a generic ListView, and I want to use the result of the method to modify the way it is displayed:

<table class="table">
    <thead>
        <td>Tournament</td>
        <td>Subscription</td>
    </thead>
    {% for tournament in tournament_list %}
        <tr>
            <td>{{ tournament.name }}</td>
            <td>
                {% if tournament.why_subscription_impossible %}
                    {{ tournament.why_subscription_impossible }}
                {% else %}
                    <a href="{% url 'ap_tournament:subscribe' tournament.id %}">Subscribe</a>
                {% endif %}
            </td>
        </tr>
    {% endfor %}
</table>

The view is a class based generic view inherited from generic.ListView.

class IndexView(generic.ListView):
    template_name = 'ap_tournament/index.html'

    def get_queryset(self):
        return Tournament.objects.all()

The shown solution doesn't work, because I need to pass the current request, to get information about logged user. So I tried to add the result of the method to a context in the view

class IndexView(generic.ListView):
    template_name = 'ap_tournament/index.html'

    def get_queryset(self):
        return Tournament.objects.all()

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)

        additional_ctx_info = []
        for tournament in self.get_queryset():
            additional_ctx_info.append({
                'reason_to_not_subscribe': tournament.why_subscription_impossible(self.request)
            })

        context['subscr_info'] = additional_ctx_info
        return context

Obviously, this doesn't work too. I don't know how to access to the subscr_info[n] with n the current index in the tournament_list. I know the forloop.counter0 to get the index, but I can't use it in the template (or I don't know how). I tried :

  • {{ subscr_info.forloop.counter0.reason_to_not_subscribe }}
  • {{ subscr_info.{{forloop.counter0}}.reason_to_not_subscribe }}

I also tried to annotate the QuerySet in get_queryset() view method and read about aggregate(), but I feel that works only with operations supported by the database (AVG, COUNT, MAX, etc.).

I also feels that using a filter or a template tag will not work in my case since I need to use the result of the method in a if tag.

Is there a better solution or a completely diffferent method to achieve what I want ?

解决方案

In your view, you could also do:

tournaments = self.get_queryset()
for tournament in tournaments:
    tournament.reason_to_not_subscribe = tournament.why_subscription_impossible(self.request)

Then add tournaments to the context.

这篇关于如何向django QuerySet的每个条目添加一些上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆