django实战系列.doc

上传人:laozhun 文档编号:2388853 上传时间:2023-02-17 格式:DOC 页数:106 大小:2.25MB
返回 下载 相关 举报
django实战系列.doc_第1页
第1页 / 共106页
django实战系列.doc_第2页
第2页 / 共106页
django实战系列.doc_第3页
第3页 / 共106页
django实战系列.doc_第4页
第4页 / 共106页
django实战系列.doc_第5页
第5页 / 共106页
点击查看更多>>
资源描述

《django实战系列.doc》由会员分享,可在线阅读,更多相关《django实战系列.doc(106页珍藏版)》请在三一办公上搜索。

1、Django实战系列(博客园专家ThinkInside 2012年初原创)Django实战系列的内容:0. 如果你以前没有接触过Django,你可能需要这些准备知识:URLconf+MTV:Django眼中的MVCDjango第一步1. 实战系列的开发目标需求分析和设计2. 从Model开始创建第一个模型类3. Model之外,你还需要知道什么Django也可以有scaffoldscaffold生成物分析4. 关于界面:静态资源,模板,及其使用引入bootstrap,设置静态资源对比RoR和Django的模板系统改造ProductList界面5. 逻辑层对比RoR与Django的输入校验机制实

2、现Product的输入校验单元测试6. 变更修改Model类增加目录页,设定统一布局7.关于会话在session中保存购物车让页面联动起来8. ajaxDjango实现RESTful web serviceDjango+jqueryajax !9. 另一轮变更提交订单自定义many-to-many关系,实现Atom订阅分页(Pagination)10. 用户和权限使用内置的Amin管理用户处理登录和注销权限控制URLconf+MTV:Django眼中的MVC MVC是众所周知的模式,即:将应用程序分解成三个组成部分:model(模型),view(视图),和 controller(控制 器)。其

3、中: M 管理应用程序的状态(通常存储到数据库中),并约束改变状态的行为(或者叫做“业务规则”)。 C 接受外部用户的操作,根据操作访问模型获取数据,并调用“视图”显示这些数据。控制器是将“模型”和“视图”隔离,并成为二者之间的联系纽带。 V 负责把数据格式化后呈现给用户。在Agile Web Development with Rails中有这样一张图对MVC模式进行了很好的解释:Django也是一个MVC框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式:M 代

4、表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。T 代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。需要注意的是,不能简单的把 Django 视图认为是MVC控制器,把 Django 模板认为MVC视图。区别在于: Django 视图 不处理用户输入,而仅仅决定要展现哪些数据给用户; Django 模板 仅仅决定如何展现Django视图

5、指定的数据。或者说, Django将MVC中的视图进一步分解为 Django视图 和 Django模板两个部分,分别决定 “展现哪些数据” 和 “如何展现”,使得Django的模板可以根据需要随时替换,而不仅仅限制于内置的模板。至于MVC控制器部分,由Django框架的URLconf来实现。URLconf设计非常巧妙,其机制是使用正则表达式匹配URL,然后调用合适的Python函数。虽然一开始有些不习惯,但是你很快就会喜欢上它,因为URLconf对于URL的规则没有任何限制,你完全可以设计成任意的URL风格,不管是传统的,RESTful的,或者是另类的。Django第一步对于一个web框架,掌

6、握了三部分的内容,就可以说是迈出了第一步。1. 准备开发环境2. 创建一个工程,并运行3. 开发hello world应用1. 准备环境 首先应该是安装python和django。这点官方网站有很详细的说明,网上也有很多教程,这里就不再重复了,只是表达一个对操作系统的观点: Mac OS:对程序员和用户都很友好 Linux: 对程序员很友好 Widows:对用户貌似友好 到底使用哪个操作系统,仁者见仁。 然后是开发工具的选择。建议抛弃IDE,使用一个好的文本编辑器。强烈推荐vim。但如果你选择Emacs,我无话可说。2. 创建工程 Django作为一个web框架,第一步应该是能够在浏览器中看到

7、页面。如果已经安装好环境的话。 首先创建工程:django-admin.py startproject depot,即开始创建名为depot的工程。 与rails相比,过程很安静,结果很干净。如下: depot/ _init_.py manage.py settings.py urls.py这几个文件的作用如下: _init_.py :Python的模块定义文件。 这是一个空文件,一般你不需要修改它。 manage.py :一个命令行工具,生成这个文件仅仅是为了方便。可以通过python manage.py help 查看该工具的功能。完全不需要编辑这个文件。 settings.py :该 D

8、jango 项目的设置或配置。 urls.py:Django项目的URL设置。与rails不同,django初始工程的文件很少,可以很容易地阅读所有的代码。但这些文件已经构成了一个可运行的Django应用。进入工程目录并运行该工程:cd depot/python manage.py runserver可以看到一些提示信息:Validating models.0 errors foundDjango version 1.3, using settings depot.settingsDevelopment server is running at http:/127.0.0.1:8000/Qui

9、t the server with CONTROL-C.29/Jan/2012 02:09:17 GET / HTTP/1.1 200 2049此时web server(开发环境!)已经运行了,用浏览器访问http:/127.0.0.1:8000/,可以看到如下的界面:说明Django已经开始工作了。3. hello Django! 与rails不同,django不需要生成controller,helper, view 等等一大堆文件,要实现一个hello程序,只需要几行代码。Django Web应用中通常包含URLconf, view, template, model 四个部分(参考URLc

10、onf+MTV:Django眼中的MVC)。但这些部分不是完全必需的。比如我们要实现一个最简单的 hello, Django!, 只需要定义URLconf和view即可。让我们把“需求”明确一下,hello,Django!实现如下功能:在浏览器中输入http:/127.0.0.1:8000/hello, 显示“hello Django!”。首先要实现一个视图(view) 来响应请求。在Django中视图是一个函数,该函数接受一个HttpRequest参数,并返回一个HttpResponse。我们可以在任何地方定义这个函数,但通常会放在Django app 的 views.py 文件中。在hel

11、lo,Django中我们不需要创建一个Django app(因为不需要model),所以可以在project 目录中创建一个view.py 文件,并定义hello(request)视图函数:depot/views.py:pythonview plaincopy1. fromdjango.httpimportHttpResponse2. 3. defhello(request):4. returnHttpResponse(hello,Django!)接下来是将前面定义的URL 映射到 这个视图函数。这是由URLconf完成的。URLconf的本质是 URL 模式以及要为该 URL 模式调用的视图

12、函数之间的映射表。打开生成的urls.py文件,先在文件前面import刚才创建的view,然后在tuple类型的变量urlpatterns中加入hello的映射关系:pythonview plaincopy1. fromdjango.conf.urls.defaultsimportpatterns,include,url2. fromdepot.viewsimporthello3. 4. urlpatterns=patterns(,5. url(rhello/$,hello),6. )此时访问 http:/127.0.0.1:8000/hello, 将会显示 hello, Django!UR

13、Lconf理解起来也很容易,即 urlpatterns中的每一项是一个二元组(正则表达式,视图函数)。当Django 接收到HTTP请求的时候,从urlpatterns中找到匹配的表达式,并将请求发生给对应的视图函数,最后视图函数返回一个HTTP响应,交给Django处理。如此而已。至此,Django的第一步已经迈出,你至少已经可以开始CGI风格的web开发了。Django实战(1):需求分析和设计Depot是Agile Web Development with Rails中的一个购物车应用。该书中用多次迭代的方法,逐步实现购物车应用,使很多人走上了rails开发的道路。遗憾的是Django世

14、界中好像没有类似的指引,也许是因为pythoner 不需要具体的例子。但是如果通过这样一个例子能够让更多的人加入pythoner的队伍,也是一大幸事。本文首先回顾一下depot的需求,在后续内容中将会按照Agile Web Development with Rails中的迭代进度,逐步用Django实现depot购物车应用。在原例子的基础上,还会增加一些新的内容,以适应企业级应用的开发。同时,会尽量展示敏捷开发的特性。原书中,初始阶段的需求整理如下:角色 买方,卖方。用例 买方:浏览产品,创建订单 卖方:管理产品,处理订单,管理发货界面设计买方界面包括: 目录页:可以选择一个产品,选中产品会打

15、开购物车页,同时该产品被加入购物车 购物车页:显示所有已选择的产品,可以返回分类页,也可以进入支付页进行支付 订单页:填写一些要素信息,确认支付后显示收据页 收据页:通知买方订单已被接收 买方界面流程如下图所示:卖方界面包括: 登录页:卖方要登录后才能使用系统,登录后通过菜单选择其要使用的功能 菜单页:选择维护产品或者查看订单 创建产品页:用于加入新的产品 产品信息页:显示已经加入的产品,可以进行修改或者删除 订单页:显示订单信息,可以忽略或者处理 卖方界面流程如下图所示:领域模型从界面设计中可以很容易得出初步的模型,如下图:以上,就是开始阶段所能得到的“需求”。尽管其中还有一些不确定的因素,

16、但是敏捷方法认为应该尽快开始开发,这些不确定的因素会在后续的迭代过程中逐步明确。接下来,就可以开始第一轮迭代开发了。Django实战(2):创建第一个模型类从模型开始开发似乎是个好主意。一方面模型是整个应用的核心,实现了应用的业务数据和对业务数据进行操作的约束,而视图和模板只是向用户提供操作和展现这些数据的界面;另一方面模型相对于系统的其他部分更加稳定,将模型先确定下来有助于系统其他部分的实现。DDD(领域驱动设计)更进一步将模型中的核心对象抽取出来作为“领域模型”。从Depot应用来看,产品(Product) 应该是模型中的核心对象之一。就让我们先来实现Product模型。创建app我们可以

17、从Django第一步中实现的工程开始。在继续之前,还要进行一些准备工作。Django约定必须要创建app才能使用模型。这也是Django的哲学之一:Django认为一个project包含很多个Django app;project提供配置文件,比如数据库连接信息、 安装的app清单、模板路径等等;而一个app是一套Django功能的集合,通常包括模型和视图,按Python的包结构的方式存在。app可以在多个project之间很容易的复用。比如Django自带的注释系统和自动管理界面。所以我们在原有工程的基础上还需要创建一个app。现在假设我们只需要一个app,并将其命名为depotapp。创建应

18、用的脚本也是使用project目录下的managy.py:$python manage.py startapp depotapp就会在工程目录下创建一个depotapp目录:depotapp/ _init_.py models.py tests.py views.py用python代码定义数据库在Django的第一印象中介绍过,Django的设计是 以Python类的形式定义数据模型。之所以没有采用rails的运行时自动获取数据库schema的”魔术方式“,是出于以下的考虑: 1. 效率。运行时扫描数据库可能会带来性能问题。 2. 明确性。只通过Model类就完全知道数据库中有哪些字段,而不需

19、要再切换到migration或schema文件中去查看,更不需要去查看数据库结构。 3. 一致性。你看到的只是Python代码,完全不需要将大脑切换到”数据库模式“,能极大提高开发效率。 4. 版本控制。rails中的数据库结构版本保存在一个个的migration文件中,这简直就是版本管理的”反模式“。Django的方式是管理Model代码文件的版本。 5. 可扩展性。可以定义数据库中不存在的”字段类型“。比如Email,URL,等等。当然,Django也提供从现有数据库表中自动扫描生成模型的工具。so,Agile Web Development with Rails中的做法是先创建数据库表:

20、sqlview plaincopy1. droptableifexistsproducts;2. createtableproducts(3. idintnotnullauto_increment,4. titlevarchar(100)notnull,5. descriptiontextnotnull,6. image_urlvarchar(200)notnull,7. pricedecimal(10,2)notnull,8. primarykey(id)9. );然后再生成scaffold(包括model,controller,test,4个views等等)。而Django的做法是,编写下

21、面的Model类:pythonview plaincopy1. depot/depotapp/models.py:2. 3. fromdjango.dbimportmodels4. 5. classProduct(models.Model):6. title=models.CharField(max_length=100)7. description=models.TextField()8. image_url=models.CharField(max_length=200)9. price=models.DecimalField(max_digits=8,decimal_places=2)如

22、同其他的ORM,ID字段是默认声明的,不需要单独处理.部署模型Django 中的每一件事情都需要明确声明,也就是说,没有你的允许,Django不会主动去碰你的代码。所以我们还需要在project中进行一些配置工作才能让app生效。不过这样的配置只需要做一次。首先要创建数据库并配置整个project的数据库连接,为了简单起见,使用sqlite数据库。在工程文件夹下创建db文件夹和sqlite数据库文件:$mkdir db$cd db$sqlite3 development.sqlite3然后修改配置文件settings.py, 将DATABASES改为:pythonview plaincopy1

23、. DATABASES=2. default:3. ENGINE:django.db.backends.sqlite3,4. NAME:db/development.sqlite3,5. USER:,6. PASSWORD:,7. HOST:,8. PORT:,9. 10. 就完成了数据库的配置。还需要配置project让depotapp生效,还是在settings.py中,将INSTALLED_APPS改为:pythonview plaincopy1. INSTALLED_APPS=(2. #django.contrib.auth,3. #django.contrib.contenttype

24、s,4. #django.contrib.sessions,5. #django.contrib.sites,6. #django.contrib.messages,7. #django.contrib.staticfiles,8. 9. #Uncommentthenextlinetoenabletheadmin:10. #django.contrib.admin,11. #Uncommentthenextlinetoenableadmindocumentation:12. #django.contrib.admindocs,13. depot.depotapp,14. )接下来就可以使用模型

25、了。先验证一下:$python manage.py validate0 errors found然后可以看一下这个Model将会生成什么样的数据库:$ python manage.py sqlall depotappBEGIN;CREATE TABLE depotapp_product ( id integer NOT NULL PRIMARY KEY, title varchar(100) NOT NULL, description text NOT NULL, image_url varchar(200) NOT NULL, price decimal NOT NULL);COMMIT;最

26、后,将模型导入数据库:$ python manage.py syncdbCreating tables .Creating table depotapp_productInstalling custom SQL .Installing indexes .No fixtures found.至此,完成了第一个模型类的创建。Django实战(3):Django也可以有scaffoldrails有一个无用的”神奇“功能,叫做scaffold。能够在model基础上,自动生成CRUD的界面。说它无用,是因为rails的开发者David说,scaffold”不是应用程序开发的目的。它只是在我们构建应用程

27、序时提供支持。当你设计出产品的列表该如何工作时,你依赖于“支架”“生成器”产生创建,更新,和删除的行为。然后在保留这个“动作”时你要替换由“生成器”生成的行为。有时候当你需要一个快速接口时,并且你并不在乎界面的丑陋,“支架”就足够用了。不要指望scaffold能满足你程序的所有需要。说它神奇,是因为在rails中你不清楚他是怎么实现的。只告诉你一句话:约定优先于配置。只要名字xxx,就会xxx。说得人云里雾里,认为rails真是一个伟大的框架。在Django的世界中没有这种无用的东西。但是如果你一定要,可以很容易地创建这么一套东西。下面我们就在project中引入一个“插件”。前面说过,app

28、可以在多个project之间很容易的复用,我们要引入的就是一个第三方的app,无需修改,只需要简单配置即可使用。这个app叫做django-groundwork。它不实现具体的功能,而是扩展了manage.py 的命令,使得通过命令行可以生成一些代码/文件。下载django-groundwork的代码:$git clone $ls django-groundworkAUTHORS LICENSE README.rst django-groundwork将其中的django-groundwork文件夹复制到project文件夹,然后在settings.py中加入该app:pythonview p

29、laincopy1. INSTALLED_APPS=(2. #django.contrib.auth,3. #django.contrib.contenttypes,4. #django.contrib.sessions,5. #django.contrib.sites,6. #django.contrib.messages,7. #django.contrib.staticfiles,8. 9. #Uncommentthenextlinetoenabletheadmin:10. #django.contrib.admin,11. #Uncommentthenextlinetoenablead

30、mindocumentation:12. #django.contrib.admindocs,13. depot.depotapp,14. django-groundwork,15. )即完成了安装。(如果遇到了什么麻烦,也可以下载本文附带的源代码包)安装后,使用$python manage.py help可以看到,列出的可用命令中多了一个groundwork。其语法是:$python manage.py groundwork appname ModelName1 ModelName2接下来使用这个app为Product生成scaffold:$python manage.py groundwo

31、rk depotapp Product,就会生成所谓的scaffold。此时运行开发服务器(python manage.py runserver),就可以访问下面的地址:http:/localhost:8000/depotapp/product/list/ 访问Product列表,并链接到create,edit,view等界面。可以下载本次迭代的源代码:Django实战(4):scaffold生成物分析在上一节用一个插件生成了类似rails的scaffold,其实无非就是URLconf+MTV。让我们看看具体都生成了哪些东西。首先是“入口”的定义即URLconf,打开urls.py:pytho

32、nview plaincopy1. fromdjango.conf.urls.defaultsimportpatterns,include,url2. fromdepot.viewsimporthello3. 4. urlpatterns=patterns(,5. url(rhello/hello),6. )7. urlpatterns+=patterns(,8. (rdepotapp/,include(depotapp.urls),9. )上面的代码中增加的配置行表示:以depotapp开头的url由depotapp/urls.py文件进行处理。django的url配置中,除了(正则表达式,

33、view函数)的方式外,还支持(正则表达式,include文件)的方式。通常把app自身相关的url写到自己的url配置文件中,然后在project中引用。接下来看一下生成的depotapp/urls.py的内容:pythonview plaincopy1. fromdjango.conf.urls.defaultsimport*2. frommodelsimport*3. fromviewsimport*4. 5. urlpatterns=patterns(,6. (rproduct/create/$,create_product),7. (rproduct/list/$,list_prod

34、uct),8. (rproduct/edit/(?P/+)/$,edit_product),9. (rproduct/view/(?P/+)/$,view_product),10. )将CRU(没有D)的URL映射到了视图。而视图在depotapp/views.py中定义:pythonview plaincopy1. fromdjangoimportforms2. fromdjango.templateimportRequestContext3. fromdjango.httpimportHttpResponse,HttpResponseRedirect4. fromdjango.templa

35、te.loaderimportget_template5. fromdjango.core.paginatorimportPaginator6. fromdjango.core.urlresolversimportreverse7. 8. #appspecificfiles9. 10. frommodelsimport*11. fromformsimport*12. 13. 14. defcreate_product(request):15. form=ProductForm(request.POSTorNone)16. ifform.is_valid():17. form.save()18.

36、 form=ProductForm()19. 20. t=get_template(depotapp/create_product.html)21. c=RequestContext(request,locals()22. returnHttpResponse(t.render(c)23. 24. 25. 26. deflist_product(request):27. 28. list_items=Product.objects.all()29. paginator=Paginator(list_items,10)30. 31. 32. try:33. page=int(request.GE

37、T.get(page,1)34. exceptValueError:35. page=136. 37. try:38. list_items=paginator.page(page)39. except:40. list_items=paginator.page(paginator.num_pages)41. 42. t=get_template(depotapp/list_product.html)43. c=RequestContext(request,locals()44. returnHttpResponse(t.render(c)45. 46. 47. 48. defview_pro

38、duct(request,id):49. product_instance=Product.objects.get(id=id)50. 51. t=get_template(depotapp/view_product.html)52. c=RequestContext(request,locals()53. returnHttpResponse(t.render(c)54. 55. defedit_product(request,id):56. 57. product_instance=Product.objects.get(id=id)58. 59. form=ProductForm(req

39、uest.POSTorNone,instance=product_instance)60. 61. ifform.is_valid():62. form.save()63. 64. t=get_template(depotapp/edit_product.html)65. c=RequestContext(request,locals()66. returnHttpResponse(t.render(c)视图中的相关内容比较多,主要的是模板,其次还有模型类、Paginator分页器、Form表单等等。基本涵盖了典型的web应用交互的内容。Django实战(5):引入bootstrap,设置静态

40、资源之前生成了Product类的scaffold,但是如同rails的开发者David所讲的那样,scaffold几乎没什么用。所以按照Agile Web Development with Rails 4th中的迭代计划,下一步的修改是美化list页面:但是这个界面还是太丑陋了。其实,有了bootstrap后,很多站点都变成了“又黑又硬”的工具条+“小清新”风格。我们即不能免俗,又懒得自已设计风格,不妨用bootstrap将产品清单界面重新设计成如下的风格:下面让我们来实现这个界面。显然web界面会使用一些静态资源(css,js,image等),要在Django中引入静态资源。Django在正

41、式部署的时候对于静态资源有特殊的处理(怎么处理?),在开发阶段,可以有简单的方式让静态资源起作用。首选在project目录下面创建一个static目录,并将静态资源按合理的组织方式放入其中:static/ css/ bootstrap.min.css js/ images/ productlist.html其中productlist.html是请界面设计师实现的产品清单静态页面;css/bootstrap.min.css 是该页面使用的样式表,来自bootstrap,将来整个系统都将使用这一套样式风格;js目录现在为空,以后可以将javascript代码放在这里;images文件夹同理。我们可以看到,Django对于静态内容的管理非常符合管理。相比之下,rails要求你将静态内容放到很怪异的结构中:app/assets/ images/ javascripts/ stylesheets/界面设计师实现的界面要想运行起来,还需要修改相关的路径,或者改变自己的目录设置习惯。这种设计让人难以理解。回到Django,让静

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号