社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

[精华] Django学习笔记(2):从一个简单的demo开始深入

BeginMan • 10 年前 • 14770 次点击  

一、简单的小demo来描述django处理流程

  1. 建立视图(view)

首先在当前目录中新建一个views.py(视图),然后编辑如下:(其实在后面教程中,这只是我们手动建立的,我们完全可以建立一个app,其中就包含它)(我们也可以先建立url映射,在建立对应的视图函数)

 #coding=utf-8

 #从django.http模块中导入HttpResponse类[1]
 from django.http import HttpResponse
 import datetime

 def current_datetime(request):      #[2]
     now=datetime.datetime.now()
     html="<html><body>现在时刻:%s.</body></html>" %now
     return HttpResponse(html)

注意:这是一段很简单、简陋的例子,具体优化见后面介绍 分析:

1. HttpResponse类位于django.http模块中,是自己手动创建,与Django自动创建的HttpRequest对象不同,在每一个视图(views)都需要实例化、处理、返回一个HttpResponse对象。

一般情况下,创建一个HttpResponse时,以字符串的形式传递页面内容给HttpResponse构造函数:

1 >>>response=HttpResponse('I am BeginMan! ')
2 >>>response=HttpResponse('HelloWorld',mimetype='text/plain')

如果希望增加内容,则可以把response当做一个类文件对象来使用

1 response=HttpResponse()
2 response.write("<p>i am beginman </p>")
3 response.write("<p>coding for fun! </p>")

其他具体信息见《Django Book》附录内容

2. 在这个(views.py)视图中每一个函数称作视图函数,视图函数都以一个HttpRequest对象为第一个参数,该参数通常命名为request

2.URL映射视图

url就像一座桥梁,通过这个桥梁我们才找到视图中对应的代码,渲染的模板(这一章暂时没有将到模板),而这一切都通过一个叫URLConf(即urls.py)的东东,在我们django-admin.py startproject mysite后,该脚本会自动建立一份URLConf(即urls.py文件),我们可以在settings.py中找到它的真身,如下:

1 。。。。。。
2 ROOT_URLCONF = 'mysite.urls'
3 。。。。。。省略

分析:

1.从django.conf.urls.defaults导入所有对象,其中包括了一个叫做patterns的函数

2.patterns()函数将处理结果保存到urlpatterns变量中,注意patterns(' ',)有块空白,它的存在就是之前的在浏览器显示的it worked 的作用。

具体URL配置见另一篇博文:"URL常用配置" 我们编辑该文件以展示current_datetime视图:

from django.conf.urls.defaults import *
 from mysite.views import current_datetime

 urlpatterns = patterns('',
     (r'^time/$',current_datetime)
 )

patterns函数中的参数其实就是一个元祖,前边是一个正则表达式的,后边是对应的视图函数,(在本demo中)在浏览器中通过输入http://127.0.0.1:8000/time ,Django在URLconf中的所有URL模式中,查找第一个匹配/time/的条目。如果匹配成功,则视图函数返回一个HttpResponse,调用current_datetime这个视图函数,Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来,(在没有模板定义的情况下)显示输出结果。

至此这一系列Django简单的处理流程就完成了。

二、Django处理请求的工作机制

记住:

1.用manage.py runserver 启动Django服务器时就载入了在同一目录下的settings.py。该文件包含了项目中的配置信息,如前面将的URLConf等,其中最重要的配置就是ROOT_URLCONF,它告诉Django哪个Python模块应该用作本站的URLConf,默认的是urls.py

2.当访问url的时候,Django会根据ROOT_URLCONF的设置来装载URLConf。

3.然后按顺序逐个匹配URLConf里的URLpatterns。如果找到则会调用相关联的视图函数,并把HttpRequest对象作为第一个参数(通常是request)

4.最后该view函数负责返回一个HttpResponse对象, enter image description here

三、深入一步:动态URL

上面一个简单的例子介绍了动态的内容,接下来深入一下url的映射,实现动态的url。

我们要做到就是在url后输入一些参数,从而实现不同的调用内容(如在url后输入数字(小时)来显示当前时间累加后的时间,如当前时间是6:20,在浏览器中输入....time/plus/3,则显示9:20)的小实例(可参见《Django Book》)

我们可以有三种不同的方法来实现: 第一种:全部写入到url中

urlpatterns = patterns('',
     (r'^time/$',current_datetime),
     (r'^time/plus/1/$',one_hour_ahead),
     (r'^time/plus/2/$',two_hour_ahead),
     (r'^time/plus/3/$',three_hour_ahead),
     ...............................
     ..................
 )

这种不解释,累死写不完。pass

第二种:URL查询字符串的形式,以?来实现,如/time/plus?hours=3。这一种在asp.net中常见的一种方式,但是在django中,它会显得臃肿、低效。pass

第三种:带通配符的URL匹配模式 因为URL模式是一个正则表达式,因此,可以使用正则表达式的技巧和URL配置技巧来实现。具体见另两篇博文:Python零碎知识(5):有关正则表达式Django总结(1):URL常用配置方法 对于本实例,可以使用 \d+ 来匹配一个或多个数字:

urlpatterns = patterns('',
2     (r'^time/$',current_datetime),
3     (r'^time/plus/\d+/$',hours_ahead),
4     (r'^time/plus/(\d{1,2})/$',hours_ahead),#或者限制最大允许99
5 )

然后我们在编写hours_ahead视图函数,整理如下:

#coding=utf-8

 #从django.http模块中导入HttpResponse类[1]
 from django.http import HttpResponse
 import datetime

 def current_datetime(request):      #[2]
     now=datetime.datetime.now()
     html="<html><body>现在时刻:%s.</body></html>" %now
     return HttpResponse(html)

 def hours_ahead(request,offset):
     offset=int(offset)
     dt=datetime.datetime.now()+datetime.timedelta(hours=offset)
     html="<html><body>In %s hours it will be %s.</body></html>" %(offset,dt)
     return HttpResponse(html)

注意:hours_ahead有两个参数,第一个request,之前已经讨论过;第二个参数offset是从匹配的URL里提取出来的,如/time/plus/10,则提取offset是10(注意字符串要int成整数才能相加)

四、小结

主要掌握了:

1.url映射基础、

2.视图函数、

3.Django处理请求的工作机制、

4.动态URL思想

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/106
 
14770 次点击  
文章 [ 6 ]  |  最新文章 10 年前
iCYB
Reply   •   1 楼
iCYB    10 年前

= =! the django book http://djangobook.py3k.cn/2.0/

BeginMan
Reply   •   2 楼
BeginMan    10 年前

@indexofire 恩恩 是的。谢谢提醒。

indexofire
Reply   •   3 楼
indexofire    10 年前

如果了解url机制,看过 django.core.urlresolvers.py 其实我们可以在 ./manage.py shell 来模拟运行一下 url 正则匹配结果

>>> from django.conf.urls import patterns, url 
>>> from mysite.views import hours_ahead
>>> r1 = patterns('', url(r'^time/plus/\d+/$', hours_ahead))
>>> r2 = patterns('', url(r'^time/plus/(\d+)/$', hours_ahead))
>>> print r1[0].regex.search('time/plus/10/').groups()
()
>>> print r2[0].regex.search('time/plus/10/').groups()
('10',)

可见 r1 没有传递‘10’作为 view func 的参数。因此,我们在写 url 匹配的时候别忘了括号!

BeginMan
Reply   •   4 楼
BeginMan    10 年前

@余泽锋1987-weibo 可能存在的原因:1、格式错误 2、请参考我这篇博文:http://www.cnblogs.com/BeginMan/archive/2013/04/26/3045392.html

indexofire
Reply   •   5 楼
indexofire    10 年前

(r'^time/plus/\d+/$',hours_ahead) 改成

(r'^time/plus/(\d+)/$',hours_ahead),

余泽锋1987-weibo
Reply   •   6 楼
余泽锋1987-weibo    10 年前

sanma,按照您写的代码,我这里出现了一些异常,麻烦您看一下, TypeError at /time/plus/10/ hours_ahead() takes exactly 2 arguments (1 given)