Django请求生命周期

首先:对于所有的web框架来说本质就是一个socket服务端,浏览器是socket客户端

路由系统

在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规则如下:

  1. from cmdb import views
  2. urlpatterns = [
  3. url(r'^login/$', views.login),
  4. url(r'^index/$', views.index),
  5. url(r'^lists/$', views.lists),
  6. url(r'^add/$', views.add),
  7. ]

2、默认URL

上面一个URL对应一个函数!我们可以在整个的url最下面里设置一个默认的URL,当用户访问我们的网站的时候没有指定详细的URL的时候我们默认让他们跳转到一个URL。

  1. urlpatterns = [
  2. url(r'^login/$', views.login),
  3. url(r'^index/$', views.index),
  4. url(r'^lists/$', views.lists),
  5. url(r'^add/$', views.add),
  6. url(r'^$', views.login),
  7. ]

这里需要注意下:当客户访问过来请求的时候,到达路由系统后是根据正则来匹配的,如果上面的匹配成功了,后面的路由规则将不会继续匹配,需要注意!!!!所以我们在后面都加一个$来做结尾

3、动态URL

3.1、动态URL传参

咱们看下园的分页连接如下图:

问:如果有这么多的RUL难道我们都要给他写一个路由规则吗?当然不是,会累死的,那他是怎么实现的呢?在上面的默认的URL中我们就说过他的路由功能是支持“正则表达式”的!

所以我们可以这么写:

  1. url(r'^user_list/(\d+)$', views.user_list),

views.user_list

  1. def user_list(request,chose_id):
  2. return HttpResponse(chose_id)

这里当用户点击的时候login后的数字,会自动的传给views.user_list作为参数,因为这个是Django调用的,不是咱们调用的。

他这里会做两步操作:

1、获取user_list后面的这个值

2、运行views.user_list这个函数,并把获取的值自动传给views.user_list作为参数他的参数

3.2、动态URL传多个参数

问:我是否可以传多个参数?

可以传多个参数它是已/来分割的。

  1. url(r'^user_list/(\d+)/(\d+)$', views.user_list),

views.user_list

  1. def user_list(request,chose_id,chose_id2):
  2. return HttpResponse(chose_id+chose_id2)

输入:http://127.0.0.1:8000/user_list/8/10  效果就是:810

他的顺序是:正序的,你先给他传那个值,第一个参数就是那个

3.3、动态URL传参数以Key:value的形式

通过正则表达式的分组来做!

  1. url(r'^user_list/(?P<v1>\d+)/(?P<V2>\d+)$', views.user_list),

这里?p<v1>这里的v1就是key,vlaue就是传进去的值,

  1. def user_list(request,v2,v1):
  2. print v2 , v1
  3. return HttpResponse(v1+v2)

这样我们就不必按照顺序去取了,可以通过key,value的方式来取传进来的值

4、URL中专(分级匹配)

在实际的生产环境中有这么一种情况:在一个project下面有很多APP,那么我们的路由规则只能写在一个文件里吗?

当然不是,我们可以通过下面的方式来把他分开:

  1. url(r'^app01/', include("app01.urls")),

然后在app01内创建一个文件urls,不要忘记注册app。然后在访问app01里的url的时候通过:hostip:port/app01/index  or  hostip:port/app01/login

5、基于反射实现动态路由设计

有很多的WEB框架,他和Django不太一样。比如mvc他会将所有的URL做成一个分类的形式。在Django中咱们一般是一个url对应一个函数。

但是在其他的WEB框架中他们也把url也进行用正则处理了。比如下面:

  1. url(r'^(?P<controller>\w+)/(?P<action>\w+)', mp),
  2. #咱们给他做个定义mp中第一个是文件比如
  3. #home.py 第二个参数是文件中的函数 def index
  4. #
  5. #/home/index/
  6. #/login/index/
  7. #/update/index/

但是上面的方法仅仅是通过反射来实现的,通过文件找到里面的函数然后执行!

但是在Django中不建议使用此方法。因为不同的WEB框架建议你使用不同的方式,Django就不建议使用反射

中间件

中间件定义:

  中间件是一个、一个的管道,如果相对任何所有的通过Django的请求进行管理都需要自定义中间件

  中间件可以对进来的请求和出去的请求进行控制

  中间件是一类。

看下面的代码在settings里中间件的类:

  1. MIDDLEWARE_CLASSES = [
  2. 'django.middleware.security.SecurityMiddleware',
  3. 'django.contrib.sessions.middleware.SessionMiddleware',
  4. 'django.middleware.common.CommonMiddleware',
  5. # 'django.middleware.csrf.CsrfViewMiddleware',
  6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  7. 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
  8. 'django.contrib.messages.middleware.MessageMiddleware',
  9. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  10. ]

2、自定义中间件

中间件中可以定义四个方法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

process_exception 这个方法只有在出现错误的时候才会触发

先写一个自定义中间件,然后在看他的原理和源码:

2.1、自定义中间件

aaarticlea/png;base64,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" alt="" />\

  1. class Testmiddle(object):
  2. def process_request(self,request):
  3. print 'Testmiddle process_request'
  4. def process_view(self, request, callback, callback_args, callback_kwargs):
  5. print 'Testmiddle process_view'
  6. def process_exception(self, request, exception):
  7. pass
  8. def process_response(self, request, response):
  9. print 'Testmiddle process_response'
  10. return response
  11.  
  12. class Nextmiddle(object):
  13. def process_request(self,request):
  14. print 'Nextmiddle process_request'
  15. def process_view(self, request, callback, callback_args, callback_kwargs):
  16. print 'Nextmiddle process_view'
  17. def process_exception(self, request, exception):
  18. pass
  19. def process_response(self, request, response):
  20. print 'Nextmiddle process_response'
  21. return response

2.2、注册中间件

  1. MIDDLEWARE_CLASSES = [
  2. 'django.middleware.security.SecurityMiddleware',
  3. 'django.contrib.sessions.middleware.SessionMiddleware',
  4. 'django.middleware.common.CommonMiddleware',
  5. # 'django.middleware.csrf.CsrfViewMiddleware',
  6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  7. 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
  8. 'django.contrib.messages.middleware.MessageMiddleware',
  9. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  10. 'middleware.middle.Testmiddle',
  11. 'middleware.middle.Nextmiddle',
  12. ]

2.3、测试使用url和views

  1. from app01 import views
  2. urlpatterns = [
  3. url(r'^admin/', admin.site.urls),
  4. url(r'^index/$', views.index),
  5.  
  6. ]
  1. def index(request):
  2. print 'This app01 Views.index'
  3. return HttpResponse('OK')

2.4、查看输出结果:

  1. '''
  2. Testmiddle process_request
  3. Nextmiddle process_request
  4. Testmiddle process_view
  5. Nextmiddle process_view
  6. This app01 Views.index
  7. Nextmiddle process_response
  8. Testmiddle process_response
  9. '''

从输出结果可以看出:

他是先执行Testmiddle 的request 方法又执行了Nextmiddle的 process_request方法。。。。

2.5、原理:

当请求进来了到达中间件

去settings里面找到MIDDLEWARE_CLASSES,MIDDLEWARE_CLASSES是一个元组

有4个列表:

  1. process_request_lsit = []
  2. process_view_list = []
  3. process_response_list = []
  4. 然后他循环MIDDLEWARE_CLASSES这个类:
  5. for in MIDDLEWARE_CLASSES
  6.   obj = 类()
  7.   if obj里有process_request方法:
  8.     process_request_lsit.append(obj.process_request)

然后循环后后执行:

  1. for i in process_request_list:
  2.   i() #加括号执行方法
  3.  
  4. for i in process_view_list:
  5. i()
  6. ............

源码:

middleware

3、中间件的流程梳理

首先看下自定义的中间件中的process_response方法他是有返回值的其他的是没有返回值的。这个return response是什么呢?

这个response就是咱们自定义的views.index返回的结果!

  1. def process_response(self, request, response):
  2. print 'Testmiddle process_response'
  3. return response

如果在其他的没有返回值得,仅有process_response有返回值得话他的请求流程是这样的:

但是如果在process_request或者process_view又返回值得话那么流程就完全不一样了!

举例:如果有m1和m2两个中间件,如果我在m1中的request方法中设置了,如果访问为1.1.1.1那么返回要一个404,那么他的访问流程是这样的:

process_exception  什么时候触发呢?咱们定义的views.index出错的时候他就会捕捉到然后执行咱们定义的process_exception方法如下图:

Django缓存

由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将 一个某个views的返回值保存至内存或者Redis中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓 存的内容拿到,并返回。

举个例子来说:如果访问量比较大的时候,有很多相同的操作比如:有时候请求的数据比如访问同一条数据,或者同一个页面的时候,其实是没必要的。

Django支持,mysql,Redis、Memecache、文件的方式做缓存,并且可以设置超时时间。

settings配置:

  1. CACHES = {
  2. 'default': {
  3. #定义已文件的方式进行cache
  4. 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
  5. #cache文件的存放路径
  6. 'LOCATION': os.path.join(BASE_DIR, 'cache'),
  7. #超时时间为600妙
  8. 'TIMEOUT': 600,
  9. 'OPTIONS': {
  10. 'MAX_ENTRIES': 1000
  11. }
  12. }
  13. }

给请求应用,就是使用装饰器

  1. from django.views.decorators.cache import cache_page
  2.  
  3. #这里设置的是 60秒 * 15 ,15分钟之后
  4. @cache_page(60 * 15)
  5. def cache_page(request):
  6. current = str(time.time())
  7. return HttpResponse(current)

Session&Cookie

Cookie就是一段字符串,保存于本机电脑上。

session 保存于服务器,用来保存用户的会话信息,依赖于Cookies

1、流程

举个例子,咱们在登录一个网站后,拿JD举例,如果我登录进去之后,在想点击订单的时候。server断怎么判断我是“我”,而不是其他人呢?

Http是短连接,那么Server端肯定有一个保存我登录状态的地方(session),那server怎么判断是我发送过来的请求呢?就是通过Cookie!

当客户端访问过来后,server端会在IE里生成一个Cookie,当访问过来的时候就可以通过Cookie进行判断

2、结构

1、自动生成一段字符串

2、将字符串发送到客户端的浏览器,同时把字符串当做key放在session里。(可以理解为session就是一个字典)

3、在用户的session对应的value里设置任意值

3、操作

3.1、操作session

  • 获取session:request.session[key]
  • 设置session:reqeust.session[key] = value
  • 删除session:del request[key]
  1. request.session.set_expiry(value)
  2. * 如果value是个整数,session会在些秒数后失效。
  3. * 如果value是个datatimetimedeltasession就会在这个时间后失效。
  4. * 如果value0,用户关闭浏览器session就会失效。
  5. * 如果valueNone,session会依赖全局session失效策略。

实例:

  1. def login(request):
  2. if request.method == 'POST':
  3. username = request.POST.get('username')
  4. password = request.POST.get('password')
  5. if username == 'shuai' and password == '123':
  6. result = request.session.get('IS_LOGIN', None)
  7. print result
  8. request.session['IS_LOGIN'] = True
  9. return redirect('/index/')
  10. obj = forms.LoginForm()
  11. # 如果登录成功,写入session,跳转index
  12. return render(request, 'account/login.html', {'model': obj})
  13.  
  14. def index(request):
  15. '''
  16. 如果用户已经登录
  17. '''
  18. is_login = request.session.get('IS_LOGIN',False)
  19. if is_login:
  20. return render(request, 'home/index.html')
  21. else:
  22. return redirect('/login/')

注:这里需要注意在session中,我们可以设置多个key:value的值,方便我们做很多事情,比如判断哪个用户:

  如果用户登录后,那么他肯定有一个cookie那么他在访问购物车的时候,怎么判断是哪个用户呢?我们可以在session设置,当用户登录的时候,我们把的用户名,增加到session中,那么用户携带cookie访问的时候,我们就能判断是哪个一用来访问的!

比如下面的对应关系:

user1

  1. cookie aaaa

server session(举例格式)

  1. {session:aaaa{'IS_LOGIN':'True',username:'shuaige'}}

 4、Session和Cookie好处

使用Session和Cookie的好处:Cookie可以理解为一个身份证ID,你只能拿着他去和Server端进行通信,如果你没有这个ID那么server端也不知道你是谁!

实例:(0 0 !)

我在写博客的时候在做Cookie和Session的实验,把Cookie删掉了!当我保存的时候直接给我提出来了,为什么呢?就是因为,server端不知道我是谁了,我已经没有密钥了。

所以,只要Session和Cookie任意一方失效,就可以理解为:

Cookie失效就相当于身份证ID过期,需要重新认证才可以继续使用。Session失效就相当于银行里的数据标识此ID无效,也需要重新申请。

Django Form表单

在实际的生产环境中比如登录和验证的时候,我们一般都使用Jquery+ajax来判断用户的输入是否为空,假如JS被禁用的话,咱们这个认证屏障是不是就消失了呢?(虽然一般不会禁用掉但是还是存在风险)

所以我们一般做两种认证一种是前端做一遍认证,在后端做一遍认证

首先咱们看一下下面的案例:

  1. #/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3. from django.shortcuts import render
  4.  
  5. # Create your views here.
  6.  
  7. def user_list(request):
  8. host = request.POST.get('host')
  9. port = request.POST.get('port')
  10. mail = request.POST.get('mail')
  11. mobile = request.POST.get('mobile')
  12. #这里有个问题,如果,这个from表单有20个input,你在这里是不是的取20次?
  13.  
  14. #验证:
  15. #输入不能为空,并且有的可以为空有的不可以为空
  16. #如果email = 11123123 这样合法吗?
  17. #如果mobile = 11123123 这样合法吗?
  18. #如果ip = 11123123 这样合法吗?
  19. '''
  20. 你在这里是不是需要做一大堆的输入验证啊?并且有很多这种页面会存在这种情况,如果每个函数都这样做估计就累死了
  21. '''
  22. return render(request,'user_list.html')

在样能解决这个问题呢?通过Django的form来实现,其他语言也有叫做(模型绑定)

Django的form的作用:

1、生成html标签

2、用来做用户提交的验证

1、生成html标签

views

  1. from django import forms
  2.  
  3. class UserInfo(forms.Form):
  4. email = forms.EmailField(required=False) #required是否可以为空,如果为False说明可以为空
  5. host = forms.CharField() #如果required不写默认为Ture
  6. port = forms.CharField()
  7. mobile = forms.CharField()
  8.  
  9. def user_list(request):
  10. obj = UserInfo() #创建了这个对象
  11. return render(request,'user_list.html',{'obj':obj})#然后把对象传给html

html调用

  1. <form action="/user_list/" method="post">
  2. <p>主机:{{ obj.host }}</p>
  3. <p>端口:{{ obj.port }}</p>
  4. <p>邮箱:{{ obj.email }}</p>
  5. <p>手机:{{ obj.mobile }}</p>
  6. <input type="submit" value="submit"/>
  7. </form>

把我们的对象穿进去,html在引用的时候直接obj.host就可以自动生成html标签,然后看下html显示:

2、简单的form表单验证用户输入的内容

  1. def user_list(request):
  2. obj = UserInfo() #创建了这个对象
  3. if request.method == 'POST':
  4. #获取用户输入一句话就搞定
  5. user_input_obj = UserInfo(request.POST)
  6. '''
  7. 咱们把post过来的数据当参数传给UserInfo咱们定义的这个类,UserInfo会自动会去你提交的数据
  8. email/host/port/mobile 自动的封装到user_input_obj里,封装到这个对象里我们就可以判断输入是否合法
  9. '''
  10. print user_input_obj.is_valid() #
  11.  
  12. return render(request,'user_list.html',{'obj':obj})#然后把对象传给html

当我们输入不合法的时候,(在创建类设置的需求)为空、或者不是email格式的时候!

这样在后端我们是不是就有一套验证的机制?就可以通过is_valid()来判断用户输入是否合法!如果不合法就把返回信息发送过去,如果合法获取数据操作即可!

捕获错误信息并返回

  1. from django import forms
  2.  
  3. class UserInfo(forms.Form):
  4. email = forms.EmailField(required=True) #required是否可以为空,如果为False说明可以为空
  5. host = forms.CharField() #如果required不写默认为Ture
  6. port = forms.CharField()
  7. mobile = forms.CharField()
  8.  
  9. def user_list(request):
  10. obj = UserInfo() #创建了这个对象
  11. if request.method == 'POST':
  12. #获取用户输入一句话就搞定
  13. user_input_obj = UserInfo(request.POST)
  14. '''
  15. 咱们把post过来的数据当参数传给UserInfo咱们定义的这个类,UserInfo会自动会去你提交的数据
  16. email/host/port/mobile 自动的封装到user_input_obj里,封装到这个对象里我们就可以判断输入是否合法
  17. '''
  18. if user_input_obj.is_valid(): #判断用户输入是否合法
  19. data = user_input_obj.clean() #获取用户输入
  20. print data
  21. else:
  22. #如果发生错误,捕捉错误
  23. error_msg = user_input_obj.errors
  24. print error_msg #打印一下然后看下他的类型
  25. '''
  26. <ul class="errorlist">
  27. <li>mobile<ul class="errorlist"><li>This field is required.
  28. </li></ul></li>
  29. <li>host<ul class="errorlist"><li>This field is required.</li></ul></li>
  30. <li>port<ul class="errorlist"><li>This field is required.</li></ul></li>
  31. </ul>
  32. '''
  33. #然后把错误信息返回
  34. return render(request,'user_list.html',{'obj':obj,'errors':error_msg,})#然后把对象传给html,在把错误信息传递过去
  35. return render(request,'user_list.html',{'obj':obj,})#然后把对象传给html

html标签,使用error输出

  1. <form action="/user_list/" method="post">
  2. <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p>
  3. <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
  4. <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
  5. <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p>
  6. <input type="submit" value="submit"/>
  7. </form>

现在在去点击下看下效果:

这样如果,我都按照要求提交,就可以取到数据了?这样咱们就不用自己去拿数据是,NICE,NICE~~

  1. {'mobile': u'123456789', 'host': u'1.1.1.1', 'email': u'shuaige@qq.com', 'port': u'8000'}

3、form表单定制化

3.1、自定义报错内容

  在form里有一个参数:error_messages  在他这里就可以定义报错内容

  1. class UserInfo(forms.Form):
  2. email = forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'}) #required是否可以为空,如果为False说明可以为空
  3. host = forms.CharField(error_messages={'required':u'主机不能为空'}) #如果required不写默认为Ture
  4. port = forms.CharField(error_messages={'required':u'端口不能为空'})
  5. mobile = forms.CharField(error_messages={'required':u'手机不能为空'})

效果:

3.2、我想给form表单添加一个属性

  1. class UserInfo(forms.Form):
  2. email = forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'}) #required是否可以为空,如果为False说明可以为空
  3. host = forms.CharField(error_messages={'required':u'主机不能为空'}) #如果required不写默认为Ture
  4. port = forms.CharField(error_messages={'required':u'端口不能为空'})
  5. mobile = forms.CharField(error_messages={'required':u'手机不能为空'},
  6. widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
  7. #这里默认是TextInput,标签
  8. )

看下效果:

3.3、在给他增加一个备注

  1. class UserInfo(forms.Form):
  2. email = forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'}) #required是否可以为空,如果为False说明可以为空
  3. host = forms.CharField(error_messages={'required':u'主机不能为空'}) #如果required不写默认为Ture
  4. port = forms.CharField(error_messages={'required':u'端口不能为空'})
  5. mobile = forms.CharField(error_messages={'required':u'手机不能为空'},
  6. widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
  7. #这里默认是TextInput,标签
  8. )
  9. #咱们在新增一个备注
  10. memo = forms.CharField(required=False,
  11. widget=forms.Textarea(attrs={'class':'form-control','placeholder':u'备注'})
  12.  
  13. )

html代码

  1. <form action="/user_list/" method="post">
  2. <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p>
  3. <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
  4. <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
  5. <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p>
  6. <p>备注:{{ obj.memo }}<span>{{ errors.memo }}</span></p>
  7.  
  8. <input type="submit" value="submit"/>
  9. </form>

4、自定义正则表达式增加判断规则

  1. import re
  2. from django import forms
  3. from django.core.exceptions import ValidationError
  4.  
  5. #自定义方法
  6. def mobile_validate(value):
  7. mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') #正则匹配
  8. if not mobile_re.match(value):
  9. raise ValidationError('手机号码格式错误') #如果没有匹配到主动触发一个错误
  10.  
  11. class UserInfo(forms.Form):
  12. email = forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'}) #required是否可以为空,如果为False说明可以为空
  13. host = forms.CharField(error_messages={'required':u'主机不能为空'}) #如果required不写默认为Ture
  14. port = forms.CharField(error_messages={'required':u'端口不能为空'})
  15.  
  16. #默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
  17. mobile = forms.CharField(validators=[mobile_validate,],#应用咱们自己定义的规则
  18. error_messages={'required':u'手机不能为空'},
  19. widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
  20. #这里默认是TextInput,标签
  21. )
  22. #咱们在新增一个备注
  23. memo = forms.CharField(required=False,
  24. widget=forms.Textarea(attrs={'class':'form-control','placeholder':u'备注'})
  25.  
  26. )

效果:

如果为空的话会提示,不能为空如果格式不对的话会提示:

5、生成select标签

  1. class UserInfo(forms.Form):
  2.  
  3. user_type_choice = (
  4. (0, u'普通用户'),
  5. (1, u'高级用户'),)
  6.  
  7. user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={'class':'form-control'}))
  8.  
  9. 。。。。。。。。。

html内

  1. <form action="/user_list/" method="post">
  2. <p>用户类型:{{ obj.user_type }}<span>{{ errors.user_type }}</span></p>
  3. <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p>
  4. <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
  5. <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
  6. <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p>
  7. <p>备注:{{ obj.memo }}<span>{{ errors.memo }}</span></p>
  8.  
  9. <input type="submit" value="submit"/>
  10. </form>

6、关于后端验证

这个后端验证是必须要有验证机制的,前端可以不写但是后端必须要写!前端的JS是可以被禁用掉到。

6、Django form漂亮的显示错误信息

设置显示error的样式

  1. error_msg = user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串
  2. #还有一个as_json

实例:

  1. import re
  2. from django import forms
  3. from django.core.exceptions import ValidationError
  4.  
  5. #自定义方法
  6. def mobile_validate(value):
  7. mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') #正则匹配
  8. if not mobile_re.match(value):
  9. raise ValidationError('手机号码格式错误') #如果没有匹配到主动出发一个错误
  10.  
  11. class UserInfo(forms.Form):
  12.  
  13. user_type_choice = (
  14. (0, u'普通用户'),
  15. (1, u'高级用户'),)
  16.  
  17. user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={'class':'form-control'}))
  18.  
  19. email = forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'}) #required是否可以为空,如果为False说明可以为空
  20. host = forms.CharField(error_messages={'required':u'主机不能为空'}) #如果required不写默认为Ture
  21. port = forms.CharField(error_messages={'required':u'端口不能为空'})
  22.  
  23. #默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
  24. mobile = forms.CharField(validators=[mobile_validate,],#应用咱们自己定义的规则
  25. error_messages={'required':u'手机不能为空'},
  26. widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
  27. #这里默认是TextInput,标签
  28. )
  29. #咱们在新增一个备注
  30. memo = forms.CharField(required=False,
  31. widget=forms.Textarea(attrs={'class':'form-control','placeholder':u'备注'}))
  32.  
  33. def user_list(request):
  34. obj = UserInfo() #创建了这个对象
  35. if request.method == 'POST':
  36. #获取用户输入一句话就搞定
  37. user_input_obj = UserInfo(request.POST)
  38.  
  39. if user_input_obj.is_valid(): #判断用户输入是否合法
  40. data = user_input_obj.clean() #获取用户输入
  41. print data
  42. else:
  43. #如果发生错误,捕捉错误
  44. error_msg = user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串
  45. #还有一个as_json
  46.  
  47. print error_msg #打印一下然后看下他的类型
  48. #然后把错误信息返回
  49. return render(request,'user_list.html',{'obj':obj,'errors':error_msg,})#然后把对象传给html,在把错误信息传递过去
  50. return render(request,'user_list.html',{'obj':obj,})#然后把对象传给html

这里在html中如果不进行处理默认显示的是:

看下他的实际是什么内容:

  1. {'mobile': [ValidationError([u'\u624b\u673a\u4e0d\u80fd\u4e3a\u7a7a'])],
  2. 'host': [ValidationError([u'\u4e3b\u673a\u4e0d\u80fd\u4e3a\u7a7a'])],
  3. 'email': [ValidationError([u'\u90ae\u7bb1\u4e0d\u80fd\u4e3a\u7a7a'])],
  4. 'port': [ValidationError([u'\u7aef\u53e3\u4e0d\u80fd\u4e3a\u7a7a'])]}

所以我们自定义一个模板语言对其进行修饰:

然后在html中调用

  1. {% load cmdb_tag %}
  2.  
  3. <!DOCTYPE html>
  4. <html lang="en">
  5. <head>
  6. <meta charset="UTF-8">
  7. <title>Shuai</title>
  8. </head>
  9. <body>
  10. <form action="/user_list/" method="post">
  11. <p>用户类型:{{ obj.user_type }}<span>{% error_message errors.user_type %}</span></p>
  12. <p>主机:{{ obj.host }}<span>{% error_message errors.host %}</span></p>
  13. <p>端口:{{ obj.port }}<span>{% error_message errors.port %}</span></p>
  14. <p>邮箱:{{ obj.email }}<span>{% error_message errors.email %}</span></p>
  15. <p>手机:{{ obj.mobile }}<span>{% error_message errors.mobile %}</span></p>
  16. <p>备注:{{ obj.memo }}<span>{% error_message errors.memo %}</span></p>
  17. <input type="submit" value="submit"/>
  18. </form>
  19. </body>
  20. </html>

显示效果如下:

因为模板语言不支持用索引的方式取值,所以我们通过自定义simp_tag来进行取值

Ajax

1、单条数据提交

在上面的原有例子中的html中新增下面html内容

  1. <form action="/user_list/" method="post">
  2. <input type="button" onclick="Ajaxsubmit();" value="提交"/>
  3. <table>
  4. <thead>
  5. <tr>
  6. <th>主机名</th>
  7. <th>端口</th>
  8. </tr>
  9. </thead>
  10. <tbody>
  11. <tr>
  12. <td>1.1.1.1</td>
  13. <td>80000</td>
  14. </tr>
  15. <tr>
  16. <td>1.1.1.1</td>
  17. <td>80000</td>
  18. </tr>
  19. </tbody>
  20. </table>
  21. </form>
  22. <script type="text/javascript" src="/static/jquery-2.2.1.min.js"></script>
  23. <script>
  24. function Ajaxsubmit(){
  25. var host = '1.1.1.1';
  26. var port = '8000';
  27.  
  28. $.ajax({
  29. url:"/ajax_data/",
  30. type:'POST',
  31. data:{h:host,p:port},
  32. success:function(arg){
  33.  
  34. }
  35. })
  36. }
  37. </script>

注释:

  1. $.ajax({
  2. url:"/ajax_data/", #目标URL
  3. type:'POST', #请求方式
  4. data:{h:host,p:port}, hpkey用户的输入为value:<QueryDict: {u'h': [u'1.1.1.1'], u'p': [u'8000']}>
  5. success:function(arg){
  6.  
  7. }

增加URL和views

  1. url(r'^ajax_data/', views.ajax_data),
  1. def ajax_data(request):
  2. print request.POST
  3. return HttpResponse('OK')

2、ajax多条数据提交

在原来的基础上修改Jquery

  1. <script>
  2. function Ajaxsubmit(){
  3. var array_users = [
  4. {'username':'shuaige','arg':18},
  5. {'username':'tianshuai','arg':18},
  6. {'username':'shuai','arg':18},
  7.  
  8. ];
  9. $.ajax({
  10. url:"/ajax_mdata/",
  11. type:'POST',
  12. data:{data:array_users},
  13. success:function(arg){
  14.  
  15. }
  16. })
  17. }
  18. </script>

添加urls&views

  1. url(r'^ajax_mdata/$', views.ajax_mdata),

views

  1. def ajax_mdata(request):
  2. print request.POST
  3. return HttpResponse('OK')

点击提交看下(在server端打印看下):

  1. <QueryDict: {u'data[1][username]': [u'tianshuai'], u'data[0][username]': [u'shuaige'], u'data[0][arg]': [u'18'], u'data[1][arg]': [u'18'], u'data[2][username]': [u'shuai'], u'data[2][arg]': [u'18']}>

上面的结果数据是有问题的!他给咱们做了个加工,咱们没给他传data[1],data[0]了吗?

所以咱们的在ajax增加参数

  1. <script>
  2. function Ajaxsubmit(){
  3. var array_users = [
  4. {'username':'shuaige','arg':18},
  5. {'username':'tianshuai','arg':18},
  6. {'username':'shuai','arg':18},
  7.  
  8. ];
  9. $.ajax({
  10. url:"/ajax_mdata/",
  11. type:'POST',
  12. tradition: true,
  13. data:{data:JSON.stringify(array_users)},
  14. success:function(arg){
  15.  
  16. }
  17. })
  18. }
  19. </script>

增加了两项:

  1. #以原生的模式传过去
  2. tradition: true,
  3.  
  4. #把数组做一步处理转成字符串
  5. data:{data:JSON.stringify(array_users)},

3、在一个Ajax请求之后,返回信息应该更职业化,不能单单发送一个字符串

看下面的就不像程序员:

  1. def ajax_data(request):
  2. print request.POST
  3. return HttpResponse('OK')

应该这么写:(下面的例子先用json来做,不过还有一个json response)

  1. import json
  2.  
  3. def ajax_data(request):
  4. ret = {'status':True,'error':''}
  5. try:
  6. print request.POST
  7. except Exception,e:
  8. ret['status'] = False
  9. ret['error'] = str(e)
  10. #在上面如果他出错我就把他ret[status] = False
  11. return HttpResponse(json.dumps(ret))

html的js也得修改下:

  1. <script>
  2. function Ajaxsubmit(){
  3. var array_users = [
  4. {'username':'shuaige','arg':18},
  5. {'username':'tianshuai','arg':18},
  6. {'username':'shuai','arg':18},
  7.  
  8. ];
  9. $.ajax({
  10. url:"/ajax_mdata/",
  11. type:'POST',
  12. tradition: true,
  13. data:{data:JSON.stringify(array_users)},
  14. success:function(arg){
  15. var callback_dict = $.parseJSON(arg);//这里把字符串转换为对象
  16. //然后咱们就可以判断
  17. if(callback_dict){//执行成功了
  18. //简单测试
  19. alert('提交成功')
  20. }else{//如果为False执行失败了
  21. alert(callback_dict.error)
  22. }
  23.  
  24. }
  25. })
  26. }
  27. </script>

python之路 django2的更多相关文章

  1. Python之路【第一篇】python基础

    一.python开发 1.开发: 1)高级语言:python .Java .PHP. C#  Go ruby  c++  ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...

  2. Python之路

    Python学习之路 第一天   Python之路,Day1 - Python基础1介绍.基本语法.流程控制              第一天作业第二天   Python之路,Day2 - Pytho ...

  3. python之路 目录

    目录 python python_基础总结1 python由来 字符编码 注释 pyc文件 python变量 导入模块 获取用户输入 流程控制if while python 基础2 编码转换 pych ...

  4. Python之路【第十九篇】:爬虫

    Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...

  5. Python之路【第十八篇】:Web框架们

    Python之路[第十八篇]:Web框架们   Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Pytho ...

  6. Python之路【第十七篇】:Django【进阶篇 】

    Python之路[第十七篇]:Django[进阶篇 ]   Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...

  7. Python之路【第十六篇】:Django【基础篇】

    Python之路[第十六篇]:Django[基础篇]   Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...

  8. Python之路【第十五篇】:Web框架

    Python之路[第十五篇]:Web框架   Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 ...

  9. Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy   Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...

随机推荐

  1. linux 命令集合收集(ubuntu)

    1.查看ubuntu版本号:cat /etc/issue  或者sudo lsb_release -a 2.查看内核版本信息:uname -a ,显示为4.4.0 x86_64版本内核

  2. PagerAdapter 普通写法

    1,viewPagre的普通写法 public ImagePagerAdapter(Context context, List<Photo> imgList) { this.mContex ...

  3. AndroidStudio gradle配置

    自2013年5月16日,在I/O大会上,谷歌推出新的Android开发环境——Android Studio,并对开发者控制台进行了改进,增加了五个新的功能, google就已经彻底放弃eclipse ...

  4. c++ const(不断跟新)

    1.把一个 const 对象的地址赋给一个普通的.非 const 对象的指针也会导致编译时的错误: const double pi = 3.14; double *ptr = π // error: ...

  5. HDU 5900 QSC and Master

    题目链接:传送门 题目大意:长度为n的key数组与value数组,若相邻的key互斥,则可以删去这两个数同时获得对应的两 个value值,问最多能获得多少 题目思路:区间DP 闲谈: 这个题一开始没有 ...

  6. 【BZOJ3436】小K的农场 差分约束

    [BZOJ3436]小K的农场 Description 背景 小K是个特么喜欢玩MC的孩纸... 描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了, ...

  7. Objective-C入门教材

    2011-05-11 15:58 三聪 cnblogs 字号:T | T 阅读本文前,你也要了解面向对象的基本概念.对象的使用以及面象对象设计模式都是bjective-C进行面向对象编程和设计Coco ...

  8. 重启svn

    重启svn svnserve -d -r /svn -d表示后台运行 -r 指定根目录是 /u02/svn

  9. [算法][LeetCode]Spiral Matrix——螺旋矩阵

    题目要求 Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spir ...

  10. spring配置文件注解方式引入的两种方式

    一.#{beanID['propertiesName']}方式 <bean id="propertyConfigurer" class="org.springfra ...