Combining two queryset into a template tag

浪子不回头ぞ 提交于 2019-12-24 10:08:39

问题


I have two models news.article and portfolio.entry. Both models have a BooleanField for setting "is_campaign" to true.

Im trying to write a custom templatetag so I can get the latest campaign article (There should only be one)

Here is my templatetag: campaign_article.py

from itertools import chain
from django import template

from news.models import Article
from portfolio.models import Entry

register = template.Library()

def get_campaign():
        #Get the newest news article with is_campaign=True
        article = Article.objects.filter(is_campaign=True).order_by('-pub_date')[:1]

        #Get the newest portfolio entry with is_campaign=True
        portfolio = Portfolio_entry.objects.filter(is_campaign=True).order_by('-pub_date')[:1]

        #combine article, and entry and display only the newest
        campaign_article = list(chain(article, portfolio))[:1]


        return {'campaign_article': campaign_article}



register.tag('campaign', get_campaign)

I have tried this in my template:

{% load campaign_article %}
{% for campaign_article in campaign %}

{{ campaign_article.id }}

{% endfor %}

But I don't get any output. Is this the wrong method ?


回答1:


You would want to create assignment_tag rather than a generic tag. So you can update your tag as:

def get_campaign():
    #your stuff
    ....

    return campaign_article

register.assignment_tag(get_campaign, name='campaign')

And update template as:

{% load campaign_article %}
{% campaign as campaign_list %} {# loads the tags and creates campaign_list context variable #}
{% for campaign_article in campaign_list %}
    {{ campaign_article.id }}
{% endfor %}



回答2:


You do not need to create template tag to do what you want. Read about the context processor:

def get_campaign(request): # this is your context processor            
        # ...    
        return {'campaign_article': campaign_article}

In your view:

def some_view(request):
    # ...
    c = RequestContext(request, {
        'foo': 'bar',
    }, [get_campaign]) # attach your context processor to template context
    return HttpResponse(t.render(c))

UPD: If you need to display the data on each page, you can register your context processor as global in your settings file. See template context processors settings.

TEMPLATE_CONTEXT_PROCESSORS = (..., "myapp.context_processors.get_campaign")

Django will automatically add variable campaign_article to each template render.



来源:https://stackoverflow.com/questions/12896577/combining-two-queryset-into-a-template-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!