使用自定义Django模板标记保持DRY

时间:2011-04-15 20:12:23

标签: python django dry django-templates

我有一个现有的模板标签,show_next_event

def show_next_event():
    try:
        e = Event.objects.filter(published='1').order_by('date').filter(date__gte=datetime.date.today())[0]
    except IndexError:
        e = ''
    return {'event': e}
register.inclusion_tag('events/next_event.html')(show_next_event)

我想抽象模板。首先想到的是将show_next_event更改为next_event,然后添加两个新功能; show_next_eventshow_next_event_badge。我希望我可以做类似以下的事情,但它不能正常工作:

def next_event():
    try:
        e = Event.objects.filter(published='1').order_by('date').filter(date__gte=datetime.date.today())[0]
    except IndexError:
        e = ''
    return {'event': e}

def show_next_event():
    next_event
register.inclusion_tag('events/next_event.html')(show_next_event)


def show_next_event_badge():
    next_event
register.inclusion_tag('events/next_event_badge.html')(show_next_event_badge)

或者是否有更好的解决方案?

2 个答案:

答案 0 :(得分:4)

Django是Python,而不是Ruby。您不能仅通过指定其名称来调用函数:您需要使用调用括号。并且Python不会自动返回函数中最后一个表达式的值:您需要使用return语句。

所以,这应该有效:

@register.inclusion_tag('events/next_event_badge.html')
def show_next_event_badge():
    return next_event()

另外,请注意我使用了装饰器语法来注册标记。

答案 1 :(得分:1)

在关注@Daniel建议后,您可以这样做以避免def s(DRY!):

show_next_event = next_event
show_next_event_badge = next_event

修改

就像这样:

def next_event():
    try:
        e = Event.objects.filter(published='1').order_by('date').filter(date__gte=datetime.date.today())[0]
    except IndexError:
        e = ''
    return {'event': e}

show_next_event = next_event
show_next_event_badge = next_event

register.inclusion_tag('events/next_event.html')(show_next_event)
register.inclusion_tag('events/next_event_badge.html')(show_next_event_badge)