DJANGO for wizard + 续篇-----WuLuoStudio

这是我们老大写的!很开心能在WuLuoStudio!不是一个人再战斗!!!

DJANGO for wizard  


仅以此文,献给WuLuoStudio的各位wizard:)。
1django 是框架,框架是什么?
在了解框架的概念之前,我们来看看客户端浏览器请求到显示网页内容这个过程,如下:
DJANGO for wizard - kymo - listen to your soul
由上图,如果没有框架的话,数据查询、生成html、数据返回三个过程我们都需要利用相应的较为底层的API去实现,而且后台cgi程序的软件架构也得自己去实现。但是框架给了我们更加方便的接口和更为合理的架构模式。
框架可以认为是采用了某种架构,集成了几大模块(数据查询、返回、生成html)的软件。php的think php,、zend framework,java的spring, hibenate, structs以及django等都属于web 框架。框架给我们提供的有操作数据库的api,使得你可以不用亲自去实现sql语言,或者说给你提供了更为高效和简洁的数据库操作接口,还给我们提供了生成动态页面的接口,因为我们需要把后台处理的结果显示在返回给客户浏览器的html文件中,所以方便的接口使得我们前端网页和后台程序可以彼此分离,这给项目管理也带来了极大方便。另外是提供了合理清晰的软件架构,如django的mvc或者说是MTV(model、template、views)一目了然。当然还有许多其他的模块,之后再介绍。

2django的模块划分
前面提到django是基于mvc架构的框架,mvc 是现在应用非常广泛的一种软件架构模式,相关概念见  百科 。但是由于django的model、template、views模块声名显赫,以下部分基本按照MTV介绍。Url主要介绍django的url配置,Model介绍django的模型,Views介绍django的视图,Template介绍django的模板,然后对一些django的小把戏做一些概要介绍。

Url
django的url匹配不得不承认真是奇葩之作,使用正则匹配的url设计,使得web 应用的url简洁明朗,它的基本过程是这样子的:
DJANGO for wizard - kymo - listen to your soul
  一般来说,django 1.4 生成一个项目之后,项目的根目录下是manage.py 和 项目名命名的文件夹,该文件夹下存在四个文件:
如图所示,urls.py里就是整个web项目的url匹配正则式模式,其他的文件待会儿一一介绍。在urls.py中,定义了正则匹配的规则,以及匹配成功之后的方法名(且当这么理解):
比如说,你访问的url为  http://www.***.com/index/,则可以加入这样一句
这里的url是一个django自带函数,它的实现如下:
即如果匹配成功,则会调用index.views.home这个方法进行处理,或者转入到另外的url匹配( 假如我们是这样子定义的匹配规则:
url(r'^index/', include('index.urls'),)。
index 即为你web 项目的应用,一般在manage.py文件所在的目录下,使用python manage.py startapp index 生成,生成一个web app后会有四个文件,如下:
  __init__.py  在里边定义的函数在外部引用时,可以直接这样使用: from index import *。
models.py 接下来会介绍,定义的是你app所需要的数据库表映射对象。
views.py 即为该app的业务处理部分,在这里定义的函数参数都有一个request对象,该对象保存了web项目的session、cookie、以及用户提交的数据等内容,并且返回必须是一个httpresponse对象。根据url的匹配规则,需要定义一个名为home的函数,如下:
然后运行 python manage.py runserver,这里顺带提一下,如果项目比较小的话,是不需要外部服务器程序支持的,因为它内嵌了一个web服务器,如果你的项目部署在自己的服务器上,那么可以python manage.py runserver (your vps ip):80,浏览器输入你vpsip或者自己绑定好的域名就可以访问你的django 网站了。

Model
在django里,model这块我知道的有以下两种:
单纯的数据模型 前文提到的django app的models.py 文件里的一些类,定义的就是web 数据库表在django里的映射对象。该对象继承了django封装好的数据库模型类,从而我们在定义自己的数据表对象之后,可以很方便的使用django模型提供的一些API,比如save()可以存数据, objects.create可以创建数据表对象等。
假如我们的网站有个项目表,定义的是项目的一些信息。我们在index的models.py可以这样定义:
  当然,在生成数据库之前,需要一些设置,首先要在settings.py中设置数据库的相关参数(数据库引擎,数据库名,用户名,密码),如下:
然后需要在settings.py中的INVALID_APPS列表中加入index。否则django无法识别该app的models.py,从而无法生成数据库。

  接着  python manage.py syncdb 

  数据库表project 就ok了。
数据库存储会在之后的views和表单处理详述。
表单数据模型 web app少不了表单请求,django有自己独特的表单模块,相见  django 表单 ,django的表单模型需要和web 的某个数据库模型一一映射,用户提交表单后,django封装的表单模型会自动进行数据的存取。这个过程相当于集成了提取表单数据和数据库操作。之后在介绍表单的时候也会详述。

Template
然后是模板系统,django的模板系统有一点个人感觉是瑕疵,需要前端人员也了解一些模板系统的设计思路。但是,这也无可厚非,单纯的前端已经很少见了。这里讲三点,首先是模板系统的设置,我们在使用之前需要设置我们的.html文件和静态文本文件(css,js)的路径。
设置template_dir,在settings.py所在目录下新建template文件夹,用以保存.html文件。
然后在settings.py中设置
  或者也可以设置为绝对路径,但是不提倡,因为开发机器上的路径并不一定和服务器上的路径是一样的。接下来设置静态文本文件路径。在settings.py中加入
  接着在工程根目录,也即manage.py所在目录下新建文件夹static,由于我们访问静态文件也是根据url的,所以,我们需要把匹配静态文件的部分也加入到url匹配文件中,如下:
要加入相应的模块支持,如下

  具体的测试见Views。
接着便是模板系统的模板语言,我们知道我们需要将后台的处理结果渲染(也就是呈现)在返回客户浏览器的html文件中,但是,django不支持像php那样的直接在html中加入php语言一样在html中加入python语句,但是,它有自己独特的一套模板语言,支持if,for等语句, 见后文例子中介绍
最后是模板继承,什么意思?比如说,我们这样一个网页
首页、日志、相册、音乐等必然都包含同样的header,如果每一个.html文件都写那部分的话,挺麻烦的,但是模板继承解决了这个问题,你需要做的事情就是定义一个顶层html文件,比如上面那个网页我可以定义一个base.html,index.html和article.html都会继承这个base.html,在base.html文件里需要被重新编排(且叫做编排)格式的地方使用 {% block block_name %}{% endblock %}注明,在index.html和article.html在文件头注明 {% extends 'base.html' %},然后在自编排的地方也同样使用 {% block block_name %} your_html_code {% endblock %},那么模板系统在解析index.html文件时,会把base.html的内容和自编排的内容整合成一个新的.html文件。
base.html(注意静态文件路径)
   index.html
注意,继承自base.html的html文件的自定义部分必须在 {% block block_name %}{% endblock %}标签内,不然模板系统不予识别。如上面的index.html中{{nihao}}这个变量(views里会说明),模板系统不会解析出来。所以index.html看起来应该是这个样子:
 
Views
视图,用来处理呈现后台返回数据、用户提交数据以及数据的处理部分。django的MVC架构中的V包含了视图和之后介绍的模板系统。
之前介绍的index app的views.py文件的作用就是定义视图函数,视图函数的两大特征前面已经介绍,这里总结一下:一、参数必须有HttpRequest对象,也即request;二、返回类型必须是一个HttpResponse对象。之前的home就是一个视图函数。
视图函数主要是做数据处理,数据呈现并将数据渲染到相应的模板html文件中。
下图所示的即为将st(st是一个字典对象)的数据传到index.html中。
  然后输入http://127.0.0.1:8000/index/,如下
之后的表单会介绍如何实现数据存储和读取。
 
Form
表单,django把表单都集成了,这点让人意外,但它就是这么做了,而且做的很出色,不管是数据检查和数据安全性都控制的十分的严格。在不使用form的时候,用户提交的表单数据一般都保存在HttpRequest对象的POST属性中,所以我们的html文件和views.py的视图函数以及urls.py看起来应该是这样子:
urls.py
  views.py
article.html
但是,你觉得这样子就能ok么?不,孩子你还天真了。它会提示你 CSRF verification failed.Request aborteddjango想的比你多,它的内嵌CSRF(反跨站)提供了一个安全的用户提交表单的环境。 网上很多人把CSRF直接给禁了!如果用户是个骇客(不能叫黑客),不好意思,不出几分钟,你的网站就要被他拿下了,所以 请相信一点:用户永远是最不可靠的:),你永远要做尽量全面的安全维护。有些人没事把你网站拿来练sql注入,练跨站攻击,坏的很。 那么怎么正确的使用csrf呢(三步走),一、在表单后面加 {% csrf_token %} 二、 在settings.py 的MIDDEL_CLASS 中加入 ’django.middleware.csrf.CsrfViewMiddleware’;三、   在视图函数中要用RequestContext来渲染表单模板。所以settings.py、views.py、article.html三个文件的局部应该是这样子:
settings.py
views.py
article.html
我们提交表单后,查询数据库,会发现数据已经存入数据库了。
  接下来,我们使用系统自带的表单类,然后自定义表单,我们在index下新建forms.py文件,用以定义form文件。如下:

然后在views里使用projectForm,看起来是这样子的:
  你的article.html看起来是这样子
  当然,如果你想自己设计自己表单的样式,那么可以这样(还记得之前说的模板语言的for吧)

  field.errors是需要你自己去定义你表单数据的规则,比如密码我可以这样定义:

  FormModel 在此不再赘述,即为form和model的综合体。
Summary:
文章好长,如有失误之处,还 望提醒。

@WuLuoStudio版权所有,如需转载,请注明出处。



DJANGO for wizard 续篇 

接着上一篇的内容,假设你现在已经了解了Django的MVC架构,这里讲讲和前端有关的一些东西,虽然有班门弄斧之嫌,但且让我抛砖引玉。这篇博文主要介绍ajax以及ajax和django的CSRF机制的冲突解决。
  ajax ,全称  Asynchronous JavaScript And XML( 异步JavaScript和XML), 是指一种创建交互式网页 应用的网页开发技术。简单的可以理解为javascript程序(一般都是用户浏览器程序)向服务器提交用户请求,并处理响应。我们知道浏览器程序提交请求的时候,必然会有一个等待返回结果的时间,这段时间内,用户被阻塞,再也无法进行下一步操作。但是,ajax使得我们在和服务器交互的时候,仍然能够进行其他的操作,这就是异步,或者也可以理解为多线程。
  在这篇博客中,用的是jQuery去实现ajax,这里提一下jQuery, jQuery使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供ajax交互。并且,更为方便的是,世界各地的js程序员为jQuery扩充了大量的开源库,使得开发出一个交互性极强、效果极炫的网站变得更加简单。首先需要下载 jQuery 的库,在你的模板文件中引入相应目录下的jQuery.js文件即可。
  <script type="text/javascript" src=“/your_directory/jQuery.js"></script> 
  接着在你的模板文件index.html中加入这段js代码:
  function reply(url){
      alert(url);
      $('<div>').load(url,
      {'messageReply':document.getElementById('messageReply').value},          
      function(){
          $('#deal').append($(this).html());
          alert('转发成功!');
      }
      );
  }
  $('div').load函数可以这样解释,将id为messageReplay的标签的值赋和messageReply组成字典(可以一次发送多个数据),通过POST方式,发送到服务器端,服务端会去处理url,如果成功,执行下面定义的那个function,一般而言我们后台会返回一段字符,$('#deal').append() 要和前面的$('<div>')一起看,即在id为 deal的div中显示服务器返回的内容,这个过程,是不需要刷新页面的。
    在html正文部分应该是这样子:
    <textarea id = 'messageReply'> </textarea>
    <input type='submit' value = 'submit' onclick='reply('\text\')>
    <div id = 'deal'></div>
  我们需要在urls.py中加入对\text\的匹配规则
  from *.views import deal_text
  #other code
  url(r'^text\', deal_text),
  然后在相应的views.py中有如下代码:
    from django.shortcuts import render_to_response
  from django.http import HttpResponse
  def deal_text(req):
    st = req.POST.get('messageReplay','')
  reply = '<div>ok</div>'
  return HttpResponse(reply)
    前面说到上面的ajax是通过post方式的,所以我们可以通过req.POST.get获取ajax提交的数据,然后返回reply的内容。但是,这样子还不行,问题在哪儿?上一篇提到说,如果是表单形式提交的话,必须加入CSRF,POST方式提交必须经过验证,方法前面提到过了,ajax的实质仍然是POST,所以仍然需要验证,不然会被认为是XSS,但是ajax怎么搞?It is easy!还记得前面表单后面的{% csrf_token %} 么,在表单提交的时候,会把{% csrf_token %}的内容也提交到后台,Django会自动进行认证。不过,在这里我们需要手动进行csrf_token的提交,不过还好有人帮我们写好了代码,把下面的代码保存为ajax.js,引入你的.html文件中即可,不过必须在jQuery引入之后进行。
    $( 'html' ).ajaxSend( function (event, xhr, settings) {  
      function  getCookie(name) {  
           var  cookieValue =  null ;  
            if  (document.cookie && document.cookie !=  '' ) {  
                         var cookies = document.cookie.split(';'); 
                         for (var i = 0; i < cookies.length; i++) {  
                             var  cookie = jQuery.trim(cookies[i]);  
                                  // Does this cookie string begin with the name we want?  
                                  if (cookie.substring(0, name.length + 1) == (name + '=')) {  
                                       cookieValue = decodeURIComponent(cookie.substring(name.length + 1));  
                                      break ;  
                            }  
                    }  
             }  
              return  cookieValue;  
          }  
         if  (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {  
             // Only send the token to relative URLs i.e. locally.   
             xhr.setRequestHeader( "X-CSRFToken" , getCookie( 'csrftoken' ));  
        }  
    });  
    然后提交ajax请求,应该不会出现403错误了。enjoy it

参考资料  jquery http://baike.baidu.com/view/1020297.htm
       ajax http://baike.baidu.com/view/1641.htm
       django 框架下使用ajax http://nswish.iteye.com/blog/967910

@WuluoStudio 版权所有  如需转载,请注明出处




猜你喜欢

转载自blog.csdn.net/superwen_go/article/details/8253724