在Django中自定义Tag和Filter(一)

2012/08/20 17:15
阅读数 213
这儿是一个自定义Tag的Demo:
  1. 创建工程和app。使用django-admin.py startproject DynamicNav命令创建一个名为DynamicNav的Django工程,然后使用manage.py startapp nav在DynamicNav目录中创建一个app。
  2. 创建目录。在DynamicNav目录中创建一个templates的目录,用来存入模板;在DynamicNav目录下创建一个 medias的目录,用来存放静态文件;在DynamicNav/Nav目录下创建一个templatetags的目录,用来存放我们的自定义tag,同 时在templatetags目录中创建一个名为__init__.py的文件,用来向Django说明这个目录存放的是源代码。
  3. 创建模板。在templates目录中创建一个nav.html的模板文件,在这个文件中只是简单的使用CSS+DIV实现了一个导航栏,CSS、DIV的相关知识大家可以去参考基它的文章。以下是该模板的源码:

nav.html:


  
  
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"  />  
  5. <title>动态导航栏演示</title>  
  6. <link href="/site_media/style.css" rel="stylesheet" type="text/css"  />  
  7. </head>  
  8. <body>  
  9.         <ul id="nav">  
  10.                 <li><a href="/" id="current">首 页</a></li>  
  11.                 <li><a href="/article/" >文 章</a></li>          
  12.                 <li><a href="/blog/" >Blog</a></li>  
  13.                 <li><a href="/forum/" >论 坛</a></li>  
  14.                 <li><a href="/about/" >联 系</a></li>                                                          
  15.         </ul>  
  16. </body>  
  17. </html>
这个模板一会还是需要修改的,不要着急~~~。 在medias目录下创建一个css文件:style.css:

  
  
  1. body  
  2. {  
  3.         background-color:#FFFFFF;  
  4. }  
  5.  
  6. #nav  
  7. {  
  8.         height:26px;  
  9.         border-bottom:2px solid #ccc;  
  10.         list-style:none;  
  11. }  
  12.  
  13. #nav li  
  14. {  
  15.         float:left;  
  16.         font-size:14px;  
  17. }  
  18.  
  19. #nav li a  
  20. {  
  21.         color:#03b;  
  22.         text-decoration:none;  
  23.         display:block;  
  24.         width:88px;  
  25.         height:19px;  
  26.         text-align:center;  
  27.         background:url(bg.gif) no-repeat;  
  28.         margin-left:8px;  
  29.         padding-top:6px;  
  30. }  
  31.  
  32. #nav li a:hover  
  33. {  
  34.         font-weight:bold;  
  35. }  
  36.  
  37. #nav li a#current  
  38. {  
  39.         background:url(cur.gif) no-repeat;  
  40.         color:#666;  
  41.         font-weight:bold;  
  42.         height:20px;  

 这段代码就定义出了下面效果的一个导航栏:

 4、修改nav/view.py文件。简单的写一下nav的view.py文件:


  
  
  1. #coding=utf-8  
  2.  
  3. from django.shortcuts import render_to_response  
  4. from django.template import RequestContext  
  5.  
  6. def index(request):  
  7.     return render_to_response('nav.html', {}, RequestContext(request))  

 

这里是将request作为参数传入模板中。

5、修改urls.py和setting.py文件。

打开urls.py后将其修改成以下内容(偷了个懒,没写那么多页面,所有的链接都使用一个页面):


  
  
  1. from django.conf.urls.defaults import *  
  2. import settings  
  3.  
  4. urlpatterns = patterns('',  
  5.     (r'^$''DynamicNav.nav.views.index'),  
  6.     (r'^article/$''DynamicNav.nav.views.index'),  
  7.     (r'^blog/$''DynamicNav.nav.views.index'),  
  8.     (r'^forum/$''DynamicNav.nav.views.index'),  
  9.     (r'^about/$''DynamicNav.nav.views.index'), 
  10.     #define the media url 
  11.     (r'^site_media/(?P<path>.*)$''django.views.static.serve', {'document_root' : settings.MEDIA_ROOT}),  

 修改setting.py的N多地方:

        1)添加templates的绝对路径到TEMPLATE_DIRS中。使用下面的语句:

os.path.join(os.path.dirname(__file__),'templates').replace('\\','/'),

记得要import os哟。

        2)将MEDIA_ROOT改成:MEDIA_ROOT = os.path.join(os.path.dirname(__file__),'medias').replace('\\','/')

        3)在INSTALLED_APPS中添加一行'DynamicNav.nav',来安装刚才建的那个APP。

        4)添加Context Processor。在setting.py的最后加上以下内容就OK了:

TEMPLATE_CONTEXT_PROCESSORS = ( 

    "django.core.context_processors.request", 

    "django.core.context_processors.auth", 

    "django.core.context_processors.debug", 

    "django.core.context_processors.i18n", 

     )

OK,现在可以运行一下manage.py runserver,打开http://127.0.0.1:8000来看一下运行效果了。

6、下面就要进行自定义tag的编写了,大家可要看好了啊~~

在nav/templatetags里建一个名为NavTag.py的文件,然后开始修改它:


  
  
  1. #coding=utf-8  
  2. from django import template  
  3.  
  4. #这句是必须滴  
  5. register = template.Library()  
  6.  
  7. #这个类是用来处理Tag的Node的,逻辑很简单  
  8. class NavTagItem(template.Node):  
  9.     def __init__(self, nav_path, nav_displaytext):  
  10.         self.path = nav_path.strip('"')  
  11.         self.text = nav_displaytext.strip('"')  
  12.           
  13.     def render(self, context):  
  14.         cur_path = context['request'].path  
  15.         #context['request']是views传入模板中的request对像,可以通过这种方法从上  
  16.         #文对象context中取得  
  17.           
  18.         current = False  
  19.         if self.path == '/':  
  20.             current = cur_path == '/'  
  21.         else:  
  22.             current = cur_path.startswith(self.path)  
  23.               
  24.         cur_id = ''  
  25.         if current:  
  26.             cur_id = ' id="current" '  
  27.               
  28.         return '<li><a %s href="%s">%s</a></li>' % (cur_id, self.path, self.text)  
  29.  
  30. #注册tag,函数基本就是这个样子,不怎么会有变化      
  31. @register .tag(name='NavTag')
  32. def navtagitem(parser, token):  
  33.     try:  
  34.         tag_name, nav_path, nav_text = token.split_contents()  
  35.     except ValueError:  
  36.         raise template.TemplateSyntaxError, \  
  37.                 "%r tag requires exactly two arguments: path and text" % \  
  38.                 token.split_contents[0]  
  39.       
  40.     return NavTagItem(nav_path, nav_text)     
7、重新修改nav.html文件。修改nav.html文件为如下内容:

  
  
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"  />  
  5. <title>动态导航栏演示</title>  
  6. <link href="/site_media/style.css" rel="stylesheet" type="text/css"  />  
  7. </head>  
  8. <body>  
  9.         {% load NavTag %}  
  10.         <ul id="nav">  
  11.                 {% navtagitem / "首 页" %}  
  12.                 {% navtagitem /article/ "文 章" %}  
  13.                 {% navtagitem /blog/ "Blog" %}  
  14.                 {% navtagitem /forum/ "论 坛" %}  
  15.                 {% navtagitem /about/ "联 系" %}                                                       
  16.         </ul>  
  17. </body>  
  18. </html> 

其中加黑的字为修改的部分。{% load NavTag %}为加载自定义tag文件,Django会自动去app下面的templatetags目录下去查找NavTag.py文件。{% navtagitem / "首 页" %}为使用tag来定义导航栏,因为首页这两个字中间有空格,所以得用双引号把它引起来,如果不引起来的话,就会被Django认为是有三个参数传到了 navtagitem标签中,从而产生TemplateSyntaxError。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部