ITPub博客

首页 > 应用开发 > Python > 在Django中使用自定义Tag创建动态导航栏

在Django中使用自定义Tag创建动态导航栏

原创 Python 作者:juyxii 时间:2020-08-28 10:23:12 0 删除 编辑

  在使用Django开发web系统时,通常会去定义一些导航栏来动态的显示当前所在的标签,类似于下面这样的:

  这个时候我们通常会将这一块定义成一个block,然后再在每个页面中进行扩展,编写和修改起来也是比较麻烦的。我通过在网看了一些高人的代码,发现可以使用自定义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

  <!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <html xmlns="http://www.w3.org/1999/xhtml">

  <head>

  <meta http-equiv="Content-Type"content="text/html;charset=utf-8"/>

  <title>动态导航栏演示</title>

  <link href="/site_media/style.css"rel="stylesheet"type="text/css"/>

  </head>

  <body>

  <ul id="nav">

  <li><a href="/"id="current">首页</a></li>

  <li><a href="/article/">文章</a></li>

  <li><a href="/blog/">Blog</a></li>

  <li><a href="/forum/">论坛</a></li>

  <li><a href="/about/">联系</a></li>

  </ul>

  </body>

  </html>

  这个模板一会还是需要修改的,不要着急~~~。

  在medias目录下创建一个css文件:style.css

  body

  {

  background-color:#FFFFFF;

  }

  #nav

  {

  height:26px;

  border-bottom:2px solid#ccc;

  list-style:none;

  }

  #nav li

  {

  float:left;

  font-size:14px;

  }

  #nav li a

  {

  color:#03b;

  text-decoration:none;

  display:block;

  width:88px;

  height:19px;

  text-align:center;

  background:url(bg.gif)no-repeat;

  margin-left:8px;

  padding-top:6px;

  }

  #nav li a:hover

  {

  font-weight:bold;

  }

  #nav li a#current

  {

  background:url(cur.gif)no-repeat;

  color:#666;

  font-weight:bold;

  height:20px;

  }

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

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

  #coding=utf-8

  from django.shortcuts import render_to_response

  from django.template import RequestContext

  def index(request):

  return render_to_response('nav.html',{},RequestContext(request))

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

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

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

  from django.conf.urls.defaults import*

  import settings

  urlpatterns=patterns('',

  (r'^$','DynamicNav.nav.views.index'),

  (r'^article/$','DynamicNav.nav.views.index'),

  (r'^blog/$','DynamicNav.nav.views.index'),

  (r'^forum/$','DynamicNav.nav.views.index'),

  (r'^about/$','DynamicNav.nav.views.index'),

  #define the media url

  (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,打开<a href="http://127.0.0.1:8000">http://127.0.0.1:8000</a>来看一下运行效果了。

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

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

  #coding=utf-8

  from django import template

  #这句是必须滴

  register=template.Library()

  #这个类是用来处理Tag的Node的,逻辑很简单

  class NavTagItem(template.Node):

  def __init__(self,nav_path,nav_displaytext):

  self.path=nav_path.strip('"')

  self.text=nav_displaytext.strip('"')

  def render(self,context):

  cur_path=context['request'].path

  #context['request']是views传入模板中的request对像,可以通过这种方法从上

  #文对象context中取得

  current=False

  if self.path=='/':

  current=cur_path=='/'

  else:

  current=cur_path.startswith(self.path)

  cur_id=''

  if current:

  cur_id='id="current"'

  return'&lt;li&gt;&lt;a%s href="%s"&gt;%s&lt;/a&gt;&lt;/li&gt;'%(cur_id,self.path,self.text)

  #注册tag,函数基本就是这个样子,不怎么会有变化

   register.tag

  def navtagitem(parser,token):

  try:

  tag_name,nav_path,nav_text=token.split_contents()

  except ValueError:

  raise template.TemplateSyntaxError,

  "%r tag requires exactly two arguments:path and text"%

  token.split_contents[0]

  return NavTagItem(nav_path,nav_text)

  7、重新修改nav.html文件。修改nav.html文件为如下内容:

  &lt;!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;

  &lt;meta http-equiv="Content-Type"content="text/html;charset=utf-8"/&gt;

  &lt;title&gt;动态导航栏演示&lt;/title&gt;

  &lt;link href="/site_media/style.css"rel="stylesheet"type="text/css"/&gt;

  &lt;/head&gt;

  &lt;body&gt;

  {%load NavTag%}

  &lt;ul id="nav"&gt;

  {%navtagitem/"首页"%}

  {%navtagitem/article/"文章"%}

  {%navtagitem/blog/"Blog"%}

  {%navtagitem/forum/"论坛"%}

  {%navtagitem/about/"联系"%}

  &lt;/ul&gt;

  &lt;/body&gt;

  &lt;/html&gt;

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

  大功告成!现在我们刷新页面后再次点击各个标签,可以动态的实现改变了,不需要再在各个页面中分别定义导航栏,提高代码的重用性和可维护性。我写的源代码在附件中,有需要的朋友可以下载。大家可以自己进一步研究一下自定义tag的用法,希望以后能和大家多多交流。写得比较快,难免有笔误,请大家多多指教。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69934488/viewspace-2715411/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2020-08-28

  • 博文量
    11
  • 访问量
    9810