设为首页 收藏本站
查看: 1813|回复: 0

[经验分享] Python框架之Django学习笔记(六)

[复制链接]

尚未签到

发表于 2015-4-23 05:28:20 | 显示全部楼层 |阅读模式
  模板
  上篇博文学习了动态视图,但是,视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python 代码之中。



1 def current_datetime(request):
2     now = datetime.datetime.now()
3     html = "It is now %s." % now
4     return HttpResponse(html)
  尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 看一下为什么:



  • 对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。




  • Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。




  • 程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。

  基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这也是Python的MVC又被称为MVT的原因。T=Template。
  
  首先,了解一下模板系统是如何独立工作的:
  在Python代码中使用Django模板的最基本方式如下:
  1.可以用原始的模板代码字符串创建一个 Template 对象, Django同样支持用指定模板文件路径的方式来创建 Template 对象;
  2.调用模板对象的render方法,并且传入一套变量context。它将返回一个基于模板的展现字符串,模板中的变量和标签会被context值替换。
  先在命令行下进入到一个工程目录下,然后执行如下命令: 



1 python manage.py shell
  
  然后在交互式解释器中执行代码:



>>> from django import template
>>> t = template.Template('My name is {{ name }}.')
>>> c = template.Context({'name': 'Adrian'})
>>> print t.render(c)
My name is Adrian.
>>> c = template.Context({'name': 'Fred'})
>>> print t.render(c)
My name is Fred.
   PS:
  如果你曾经使用过Python,你一定好奇,为什么我们运行python manage.py shell而不是python。这两个命令都会启动交互解释器,但是manage.py shell命令有一个重要的不同: 在启动解释器之前,它告诉Django使用哪个设置文件。 Django框架的大部分子系统,包括模板系统,都依赖于配置文件;如果Django不知道使用哪个配置文件,这些系统将不能工作。
  如果你想知道,这里将向你解释它背后是如何工作的。 Django搜索DJANGO_SETTINGS_MODULE环境变量,它被设置在settings.py中。例如,假设mysite在你的 Python搜索路径中,那么DJANGO_SETTINGS_MODULE应该被设置为:’mysite.settings’
  当你运行命令:python manage.py shell,它将自动帮你处理DJANGO_SETTINGS_MODULE。 在当前的这些示例中,我们鼓励你使用`` python manage.py shell``这个方法,这样可以免去你大费周章地去配置那些你不熟悉的环境变量。
    随着你越来越熟悉Django,你可能会偏向于废弃使用`` manage.py shell`` ,而是在你的配置文件.bash_profile中手动添加 DJANGO_SETTINGS_MODULE这个环境变量。
  当你创建一个 Template 对象,模板系统在内部编译这个模板到内部格式,并做优化,做好 渲染的准备。 如果你的模板语法有错误,那么在调用 Template() 时就会抛出 TemplateSyntaxError 异常:



>>> from django.template import Template
>>> t = Template('{% notatag %}')
Traceback (most recent call last):
File "", line 1, in ?
...
django.template.TemplateSyntaxError: Invalid block tag: 'notatag'
  
  这里,块标签(block tag)指向的是`` {% notatag %}``,块标签与模板标签是同义的。
  系统会在下面的情形抛出 TemplateSyntaxError 异常:


  • 无效的tags
  • 标签的参数无效
  • 无效的过滤器
  • 过滤器的参数无效
  • 无效的模板语法
  • 未封闭的块标签 (针对需要封闭的块标签)
  模板渲染
  一旦创建一个 Template 对象,可以用 context 来传递数据给它。 一个context是一系列变量和它们值的集合。
  context在Django里表现为 Context 类,在 django.template 模块里。 它的构造函数带有一个可选的参数: 一个字典映射变量和它们的值。 调用 Template 对象 的 render() 方法并传递context来填充模板:



>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
u'My name is Stephane.'
  
  一个模板,多个Context
  一旦有了模板对象,它可以被多个Context对象渲染, 例如:



>>> from django.template import Template, Context
>>> t = Template('Hello, {{ name }}')
>>> print t.render(Context({'name': 'John'}))
Hello, John
>>> print t.render(Context({'name': 'Julie'}))
Hello, Julie
>>> print t.render(Context({'name': 'Pat'}))
Hello, Pat
  
  Django 模板解析非常快捷。 大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。 这和基于 XML 的模板引擎形成鲜明对比,那些引擎承担了 XML 解析器的开销,且往往比 Django 模板渲染引擎要慢上几个数量级。
  视图中使用模板
  在学习了模板系统的基础之后,现在要使用相关知识来创建视图。 重新打开刚刚在 mysite.views 中创建的 current_datetime 视图。 以下是其内容:



1 from django.http import HttpResponse
2 import datetime
3
4 def current_datetime(request):
5     now = datetime.datetime.now()
6     html = "It is now %s." % now
7     return HttpResponse(html)
  
  先用 Django 模板系统来修改该视图。 第一步,首先想到的是要做下面这样的修改:



1 from django.template import Template, Context
2 from django.http import HttpResponse
3 import datetime
4
5 def current_datetime(request):
6     now = datetime.datetime.now()
7     t = Template("It is now {{ current_date }}.")
8     html = t.render(Context({'current_date': now}))
9     return HttpResponse(html)
  
  没错,它确实使用了模板系统,但是并没有解决我们在本章开头所指出的问题。 也就是说,模板仍然嵌入在Python代码里,并未真正的实现数据与表现的分离。 让我们将模板置于一个 单独的文件 中,并且让视图加载该文件来解决此问题。
  为了解决这些问题,我们采用了 模板自加载模板目录 的技巧.
  模板加载
  为了减少模板加载调用过程及模板本身的冗余代码,Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板,
  要使用此模板加载API,首先你必须将模板的保存位置告诉框架。 设置的保存文件就是我们前一章节讲述ROOT_URLCONF配置的时候提到的 settings.py。
  在settings.py文件的第32行左右找到以下代码:



1 INSTALLED_APPS = (
2     'django.contrib.admin',
3     'django.contrib.auth',
4     'django.contrib.contenttypes',
5     'django.contrib.sessions',
6     'django.contrib.messages',
7     'django.contrib.staticfiles',
8 )
  
  然后在第2行位置加入工程,做法如下:



1 INSTALLED_APPS = (
2     'mysite',                               #新加入的工程
3     'django.contrib.admin',
4     'django.contrib.auth',
5     'django.contrib.contenttypes',
6     'django.contrib.sessions',
7     'django.contrib.messages',
8     'django.contrib.staticfiles',
9 )
  
  接下来,在mysite的项目中创建templates文件夹,然后在里面创建包括以下模板代码 current_datetime.html 文件,代码如下:



1
2
3 It is now {{ current_date }}
4
5
  
  然后,就是修改你的视图文件了,进行如下修改: 



1 from django.template.loader import get_template
2 from django.template import Context
3 from django.http import HttpResponse
4 import datetime
5
6 def current_datetime(request):
7     now = datetime.datetime.now()
8     t = get_template('current_datetime.html')
9     html = t.render(Context({'current_date': now}))
10     return HttpResponse(html)
  
  此范例中,我们使用了函数 django.template.loader.get_template() ,而不是手动从文件系统加载模板。 该 get_template() 函数以模板名称为参数,在文件系统中找出模块的位置,打开文件并返回一个编译好的 Template 对象。
  一些小技巧
  使用 render_to_response() 重新编写过的 current_datetime 范例。



1 from django.shortcuts import render_to_response
2 import datetime
3
4 def current_datetime(request):
5     now = datetime.datetime.now()
6     return render_to_response('current_datetime.html', {'current_date': now})
  
  大变样了有木有!


  • 不再需要导入 get_template 、 Template 、 Context 和 HttpResponse 。相反,我们导入 django.shortcuts.render_to_response 。 import datetime 继续保留。
  • 在 current_datetime 函数中,我们仍然进行 now 计算,但模板加载、上下文创建、模板解析和 HttpResponse 创建工作均在对 render_to_response() 的调用中完成了。 由于 render_to_response() 返回 HttpResponse 对象,因此我们仅需在视图中 return 该值。
  render_to_response() 的第一个参数必须是要使用的模板名称。 如果要给定第二个参数,那么该参数必须是为该模板创建 Context 时所使用的字典。 如果不提供第二个参数, render_to_response() 使用一个空字典。
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59672-1-1.html 上篇帖子: Python Twisted 框架中 socket通信 下篇帖子: arcgis python 图形有关操作
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表