Django 如何在clusion_tag 中渲染自定义模板标签以将其显示在base.html 中
你好,我是 Django 初学者。
我有一个日历,希望在网页的每个网站上显示,因此我在 base.html 中将此称为 {% include "tags/my_calendar.html" %}
。
据我所知,到目前为止,我可以通过创建自定义模板标签或在标准 Django 视图中使用它来显示日历。我用标准 Django 视图测试了它,通过 urls.py 调用日历函数,效果很好。 但我不希望仅针对特殊网址显示日历。
那么我可以通过定义自定义模板标签来做到这一点吗?
到目前为止我尝试过:
from django import template
register = template.Library()
@register.inclusion_tag("tags/my_calendar.html")
def calendar():
"""
Show calendar of events for specified month and year
"""
lToday = datetime.now()
lYear = lToday.year
lMonth = lToday.month
my_workouts = ContestEvent.objects.filter(id__year=lYear, id__month=lMonth)
lCalendar = WorkoutCalendar(my_workouts).formatmonth(lYear, lMonth)
return {'calendar': mark_safe(lCalendar)}
我按如下方式重写 HTMLCalender 类,所有这些都适用于前面提到的 Django 标准视图,但返回 render_to_response:
class WorkoutCalendar(HTMLCalendar):
def __init__(self, workouts):
super(WorkoutCalendar, self).__init__()
# self.workouts = self.group_by_day(workouts)
def formatday(self, day, weekday):
if day != 0:
cssclass = self.cssclasses[weekday]
if date.today() == date(self.year, self.month, day):
cssclass += ' today'
return self.day_cell(cssclass, day)
return self.day_cell('noday', ' ')
def formatmonth(self, year, month):
self.year, self.month = year, month
return super(WorkoutCalendar, self).formatmonth(year, month)
def day_cell(self, cssclass, body):
return '<td class="%s">%s</td>' % (cssclass, body)
我的 \tags\my_calendar.html 看起来像这样:
{% load calendar_tag %}
<div>
{% calendar %}
</div
我本质上做错了什么?我收到以下错误:
Request Method: GET
Request URL: http://127.0.0.1:8000/de/
Exception Type: TemplateSyntaxError
Exception Value:
Caught an exception while rendering: maximum recursion depth exceeded
update1 在 Daniel Roseman 的提示下使用变量语法 {{ calendar }}
我摆脱了递归错误,而不是标记语法 {% calendar %}
,但我的日历仍然没有显示。我做了很多调查。
这里有什么问题吗?
更新2 经过一番调查,我发现这个有用的简短描述如何使用自定义模板标签。 日历没有显示的错误是我在 base.html 中调用 {% include "tags/my_calendar.html" %}
,而不是调用我的标签的函数{%日历<参数>; %}
。而我的标签模板没问题,它调用标签函数的返回值:
Hello I'm a Django Beginner.
I have a calendar that I want to be displayed on every site of my webpage, so I call this {% include "tags/my_calendar.html" %}
in my base.html.
As I know so far, I can either display the calendar by creating a custom template tag or by using it in a standard Django view. I tested it with a standard Django view, by calling the calendar function through a urls.py, that works fine.
But I don't want the calendar being only displayed for a special url.
So can I do this by defining a custom template tag?
I tried this so far:
from django import template
register = template.Library()
@register.inclusion_tag("tags/my_calendar.html")
def calendar():
"""
Show calendar of events for specified month and year
"""
lToday = datetime.now()
lYear = lToday.year
lMonth = lToday.month
my_workouts = ContestEvent.objects.filter(id__year=lYear, id__month=lMonth)
lCalendar = WorkoutCalendar(my_workouts).formatmonth(lYear, lMonth)
return {'calendar': mark_safe(lCalendar)}
I override the HTMLCalender class as follows and all this works with Django standard view as mentioned before, but returning a render_to_response:
class WorkoutCalendar(HTMLCalendar):
def __init__(self, workouts):
super(WorkoutCalendar, self).__init__()
# self.workouts = self.group_by_day(workouts)
def formatday(self, day, weekday):
if day != 0:
cssclass = self.cssclasses[weekday]
if date.today() == date(self.year, self.month, day):
cssclass += ' today'
return self.day_cell(cssclass, day)
return self.day_cell('noday', ' ')
def formatmonth(self, year, month):
self.year, self.month = year, month
return super(WorkoutCalendar, self).formatmonth(year, month)
def day_cell(self, cssclass, body):
return '<td class="%s">%s</td>' % (cssclass, body)
My \tags\my_calendar.html looks like this:
{% load calendar_tag %}
<div>
{% calendar %}
</div
What am I doing essentially wrong? I got the following error:
Request Method: GET
Request URL: http://127.0.0.1:8000/de/
Exception Type: TemplateSyntaxError
Exception Value:
Caught an exception while rendering: maximum recursion depth exceeded
update1
With the hint of Daniel Roseman to make use of variable syntax {{ calendar }}
instead of the tag syntax {% calendar %}
I got rid of the recursion error, but my calendar is still not displayed. I make a lot of investigations.
What is wrong here?
update2
after some investigation, I found this helpful short description on how to use custom template tag.
The mistake why the calender didn't show up, was that I was calling {% include "tags/my_calendar.html" %}
in the base.html, instead of calling the function of my tag as {% calendar <parameter> %}
. Whereas my tag template was ok, which calls the returned value of the tag function:
{{ calendar }}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的递归错误是因为您在由同一标记呈现的模板内调用
calendar
标记。您的 /tags/my_calendar.html 文件实际上应该如下所示:
请注意变量语法的使用,以表明您正在渲染传递到上下文中的值,而不是标记语法。您也不需要使用
load
。Your recursion error is because you are calling the
calendar
tag inside the template being rendered by that very same tag.Your /tags/my_calendar.html file should actually look like this:
Note the use of the variable syntax, to show you're rendering the value passed into the context, rather than the tag syntax. You don't need to use
load
, either.如果日历要显示在站点的每个页面中,那么在 context_processor 中创建日历的控制器更有意义。这样,字段就会添加到每个模板都可用的 Request 对象中,然后将日历视图嵌入到基本模板中。
James Bennet 描述得很清楚: http: //www.b-list.org/weblog/2006/jun/14/django-tips-template-context-processors/
如果您将调用附加到日历作为闭包或仿函数对象,顺便说一句,您可以避免在那些不渲染的页面上产生交易成本。这就是 QuerySet 的作用,也是为什么它在实际请求数据之前不与数据库进行事务处理。
If the calendar is going to be displayed in each and every page of your site, then it makes more sense to create the calendar's controller in a context_processor. This way, the fields are added to the Request object that is available to every template, and then just embed the calendar view in your base template.
James Bennet describes it clearly: http://www.b-list.org/weblog/2006/jun/14/django-tips-template-context-processors/
If you attach the call to the calendar as a closure or functor object, by the way, you can avoid the transaction costs on those pages where you don't render it. This is what QuerySet does, and why it doesn't transact with the database until the data is actually requested.