python middle_Python学习高级篇(四)

概要

一、路由系统

1、默认处理函数

2、动态url

3、分级匹配

4、基于反射实现的动态路由

二、中间件

对于所有请求做处理时===》定义中间件

功能:拿到请求ip后禁用一下

三、Model(*)

1、创建表

2、操作表数据

四、Form(*)

1、用户提交数据验证

2、生成html标签

五、cookie和session

六、跨站请求伪造,跨站脚本攻击

七、Ajax(*)

八、Admin

九、缓存

十、自定义分页(*)

Django学习基础篇

关于python的web框架那点事

Flask:基于Werkzeug 和 Jinja2的微型Python框架,它的目的是更快地上手,适合初学者使用。参考果壳网。

Django:全能型框架,目的是为了让开发者能够 快速 地开发一个网站,它提供了很多模块,集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。咱们接下来的主人公就是这位了。。。

Tornado:传说中性能高高的框架,是一个异步网络库,通过使用非阻塞I/O,Tornado可以处理数以万计打开的链接,这使它成为长轮询、WebSocket和其他需要为用户提供长连接的应用的理想选择。参考知乎。

基本配置

一、创建django程序

终端命令:django-admin startproject sitename

IDE创建Django程序时,本质上都是自动执行上述命令

其他常用命令

运行程序:python manage.py runserver

创建APP:python manage.py startapp appname

同步数据库:python manage.py syncdb

python manage.py makemigrations

python manage.py migrate

创建超级用户:python manage.py createsuperuser

二、程序目录

三、配置文件settings.py

1、数据库

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

}

2、模板

TEMPLATES = [

{

'BACKEND': 'django.template.backends.django.DjangoTemplates',

'DIRS': [os.path.join(BASE_DIR, 'templates')]

,

'APP_DIRS': True,

'OPTIONS': {

'context_processors': [

'django.template.context_processors.debug',

'django.template.context_processors.request',

'django.contrib.auth.context_processors.auth',

'django.contrib.messages.context_processors.messages',

],

},

},

]

3、静态文件

STATIC_URL = '/static/'

STATICFILES_DIRS = [

os.path.join(BASE_DIR, 'static'),

]

模板template

1、模版的执行

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

def current_datetime(request):

now = datetime.datetime.now()

html = "

It is now %s." % now

return HttpResponse(html)

from django import template

t = template.Template('My name is {{ name }}.')

c = template.Context({'name': 'Adrian'})

print t.render(c)

import datetime

from django import template

import DjangoDemo.settings

now = datetime.datetime.now()

fp = open(settings.BASE_DIR+'/templates/Home/Index.html')

t = template.Template(fp.read())

fp.close()

html = t.render(template.Context({'current_date': now}))

return HttpResponse(html)

from django.template.loader import get_template

from django.template import Context

from django.http import HttpResponse

import datetime

def current_datetime(request):

now = datetime.datetime.now()

t = get_template('current_datetime.html')

html = t.render(Context({'current_date': now}))

return HttpResponse(html)

return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))

2、模版语言

模板中也有自己的语言,该语言可以实现数据展示

{{ item }}

{% for item in item_list %} {{ item }} {% endfor %}

forloop.counter

forloop.first

forloop.last

{% if ordered_warranty

%} {% else %} {% endif %}

母板:{% block title %}{%

endblock %}

子板:{% extends "base.html" %}

{% block title %}{% endblock %}

帮助方法:

{{ item.event_start|date:"Y-m-d H:i:s"}}

{{ bio|truncatewords:"30" }}

{{ my_list|first|upper }}

{{ name|lower }}

3、自定义simple_tag

a、在app中创建templatetags模块

b、创建任意 .py 文件,如:xx.py

#!/usr/bin/env python

#coding:utf-8

from django import template

from django.utils.safestring import mark_safe

from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

@register.simple_tag

def my_simple_time(v1,v2,v3):

return v1 + v2 + v3

@register.simple_tag

def my_input(id,arg):

result = "" %(id,arg,)

return mark_safe(result)

c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

{% load xx %}

d、使用simple_tag

{% my_simple_time 1 2 3%}

{% my_input 'id_username' 'hide'%}

e、在settings中配置当前app,不然django无法找到自定义的simple_tag

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'app01',

]

路由系统urls.py

1、每个路由规则对应一个view中的函数

urlpatterns = [

url(r'^admin/', admin.site.urls),

]

2、根据app对路由规则进行一次分类

url(r'^web/', include('web.urls')),

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

Urls.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from django.conf.urls import include, url

from django.contrib import admin

from app01 import views

def md():

pass

urlpatterns = [

url(r'^admin/', include(admin.site.urls)),

# 交给app01/urls.py处理

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

# url(r'^index/$', views.index),

# url(r'^user_list/(\d+)/(\d+)$', views.user_list), # 基于正则表达式

# url(r'^user_list/(?P\d+)/(?P\d+)$', views.user_list), # 参数设置为v1,v2

# url(r'^$', views.index),

]

App01/urls.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from django.conf.urls import include, url

from django.contrib import admin

from app01 import views

urlpatterns = [

url(r'index/$', views.index),

url(r'cache/$', views.cache_page),

url(r'login/$', views.login),

url(r'home/$', views.home),

url(r'logout/$', views.logout),

]

App01/views.py

# -*- coding:utf-8 -*-

from django.shortcuts import render,HttpResponse,redirect

import time

from django.views.decorators.cache import cache_page

db = {

'alex': "asdfasdfasdasdfasdf",

'eirc': '11111111111',

}

def login(request):

if request.method == "POST":

username = request.POST.get('username')

pwd = request.POST.get('pwd')

if username == 'alex' and pwd == '123':

request.session['IS_LOGIN'] = True

request.session['USRNAME'] = 'alex'

return redirect('/app01/home/')

elif username == 'eirc' and pwd == '123':

request.session['IS_LOGIN'] = True

request.session['USRNAME'] = 'eirc'

return redirect('/app01/home/')

return render(request, 'login.html')

def home(request):

is_login = request.session.get('IS_LOGIN', False)

if is_login:

print request.session,type(request.session)

username = request.session.get('USRNAME', False)

data = db[username]

# return HttpResponse(data)

return render(request, 'home.html', {'username': username})

else:

return redirect("/app01/login/")

def logout(request):

# del request.session['IS_LOGIN']

# del reques

from django.contrib.sessions.backends.db import SessionStore

# print request.session._session_key

del request.session['IS_LOGIN']

request.session.delete(request.session._session_key)

return redirect('/app01/login/')

@cache_page(60 * 15)

def cache_page(request):

current = str(time.time())

return HttpResponse(current)

def index(request):

raise Exception('bb')

return HttpResponse('ok')

#

# def user_list(request, nid, page):

# print nid,page

# return HttpResponse(nid+page)

def user_list(request, v2, v1):

print v1,v2

return HttpResponse(v1+v2)

通过反射机制,为django开发一套动态的路由系统Demo:

Readme.txt

该实例通过反射机制实现Django的动态路由

主要代码实现

1、url.py

配置url映射

2、activator.py

根据url中获取的参数,通过反射调用指定 app/view.py 中的函数

如:

http://127.0.0.1:9000/app01/index/ ==》 执行app01/view.py文件中的index函数

http://127.0.0.1:9000/app02/index/ ==》 执行app02/view.py文件中的index函数

http://127.0.0.1:9000/app01/login/ ==》 执行app01/view.py文件中的login函

settings.py

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production

# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = '%b*ah#)lb500*yzykxe0t_z4pzzs_q06e=!a5$2k^s&%3%@m%('

# SECURITY WARNING: don't run with debug turned on in production!

DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = (

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

)

MIDDLEWARE_CLASSES = (

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.auth.middleware.SessionAuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

)

ROOT_URLCONF = 'DynamicRouter.urls'

WSGI_APPLICATION = 'DynamicRouter.wsgi.application'

# Database

# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

}

# Internationalization

# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

# https://docs.djangoproject.com/en/1.7/howto/static-files/

STATIC_URL = '/static/'

urls.py

from django.conf.urls import patterns, include, url

from django.contrib import admin

from DynamicRouter.activator import process

urlpatterns = patterns('',

# Examples:

# url(r'^$', 'DynamicRouter.views.home', name='home'),

# url(r'^blog/', include('blog.urls')),

url(r'^admin/', include(admin.site.urls)),

('^(?P(\w+))/(?P(\w+))/(?P(\d+))/(?P(\d+))/$',process),

('^(?P(\w+))/(?P(\w+))/(?P(\d+))/$',process),

('^(?P(\w+))/(?P(\w+))/$',process),

('^(?P(\w+))/$',process,{'function':'index'}),

)

activator.py

#!/usr/bin/env python

#coding:utf-8

from django.shortcuts import render_to_response,HttpResponse,redirect

def process(request,**kwargs):

'''接收所有匹配url的请求,根据请求url中的参数,通过反射动态指定view中的方法'''

app = kwargs.get('app',None)

function = kwargs.get('function',None)

try:

appObj = __import__("%s.views" %app)

viewObj = getattr(appObj, 'views')

funcObj = getattr(viewObj, function)

#执行view.py中的函数,并获取其返回值

result = funcObj(request,kwargs)

except (ImportError,AttributeError),e:

#导入失败时,自定义404错误

return HttpResponse('404 Not Found')

except Exception,e:

#代码执行异常时,自动跳转到指定页面

return redirect('/app01/index/')

return result

App01/views.py

from django.shortcuts import render

from django.http.response import HttpResponse

# Create your views here.

def index(request,kwargs):

return HttpResponse('app01.index')

App02/views.py

from django.shortcuts import render

from django.http.response import HttpResponse

# Create your views here.

def index(request,kwargs):

return HttpResponse('app02.index')

App03/views.py

from django.shortcuts import render

from django.http.response import HttpResponse

# Create your views here.

def index(request,kwargs):

return HttpResponse('app03.index')

admin

django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin 则需要以下步骤:

创建后台管理员

配置url

注册和配置django admin后台管理页面

1、创建后台管理员

python manage.py createsuperuser

2、配置后台管理url

url(r'^admin/', include(admin.site.urls))

3、注册和配置django admin 后台管理页面

a、在admin中执行如下配置

from django.contrib import admin

from app01 import models

admin.site.register(models.UserType)

admin.site.register(models.UserInfo)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

b、设置数据表名称

class UserType(models.Model):

name = models.CharField(max_length=50)

class Meta:

verbose_name = '用户类型'

verbose_name_plural = '用户类型'

c、打开表之后,设定默认显示,需要在model中作如下配置

class UserType(models.Model):

name = models.CharField(max_length=50)

def __unicode__(self):

return self.name

from django.contrib import admin

from app01 import models

class UserInfoAdmin(admin.ModelAdmin):

list_display = ('username', 'password', 'email')

admin.site.register(models.UserType)

admin.site.register(models.UserInfo,UserInfoAdmin)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

d、为数据表添加搜索功能

from django.contrib import admin

from app01 import models

class UserInfoAdmin(admin.ModelAdmin):

list_display = ('username', 'password', 'email')

search_fields = ('username', 'email')

admin.site.register(models.UserType)

admin.site.register(models.UserInfo,UserInfoAdmin)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

e、添加快速过滤

from django.contrib import admin

from app01 import models

class UserInfoAdmin(admin.ModelAdmin):

list_display = ('username', 'password', 'email')

search_fields = ('username', 'email')

list_filter = ('username', 'email')

admin.site.register(models.UserType)

admin.site.register(models.UserInfo,UserInfoAdmin)

admin.site.register(models.UserGroup)

admin.site.register(models.Asset)

Django学习进阶篇

Django请求生命周期原理【面试必备】

实现机制:

先去执行settings里的middleware的所有类,根据类执行相应的列表;

1、请求

2、Django自动去 setttings里找 MIDDLEWARE_CLASSES ,元祖

3、

MIDDLEWARE_CLASSES = (

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.auth.middleware.SessionAuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

'django.middleware.security.SecurityMiddleware',

'middleware.middle1.mmm',

'middleware.middle1.xxx',

)

process_request_list = []

process_view_list = []

process_response_list = []

process_exception_list = []

for 类 in MIDDLEWARE_CLASSES:

obj = 类()

if obj里有process_request方法:

process_request_list.append(obj.process_request)

for i in process_request_list:

i()

for i in process_view_list:

i()

views里的函数

for i in process_response_list:

i()

obj.process_request

中间件

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。

与mange.py在同一目录下的文件夹 wxy/middleware下的auth.py文件中的Authentication类

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

process_request(self,request)

process_view(self, request, callback, callback_args, callback_kwargs)

process_exception(self, request, exception)

process_response(self, request, response)

以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

自定义中间件

1、创建中间件类

class RequestExeute(object):

def process_request(self,request):

pass

def process_view(self, request, callback, callback_args, callback_kwargs):

i =1

pass

def process_exception(self, request, exception):

pass

def process_response(self, request, response):

return response

2、注册中间件

MIDDLEWARE_CLASSES = (

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.auth.middleware.SessionAuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

'wxy.middleware.auth.RequestExeute',

)

DEM0:

目录结构如下:

Settings.py

INSTALLED_APPS = (

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'app01',

)

MIDDLEWARE_CLASSES = (

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

#'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.auth.middleware.SessionAuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

'django.middleware.security.SecurityMiddleware',

'middleware.middle1.mmm',

'middleware.middle1.xxx',

)

urls.py

from django.conf.urls import include, url

from django.contrib import admin

from app01 import views

def md():

pass

urlpatterns = [

url(r'^admin/', include(admin.site.urls)),

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

# home.py def index

# /home/index

# /aa/vv

# /uu/vwwv

# 只是基于反射

url(r'^index/$', views.index),

url(r'^index1/$', views.index),

url(r'^home/$', views.index),

url(r'^sd/$', views.index),

url(r'^fff/$', views.index),

url(r'^aa/$', views.index),

# url(r'^index/$', views.index),

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

# url(r'^user_list/(?P\d+)/(?P\d+)$', views.user_list),

# url(r'^$', views.index),

]

app01/views.py

# -*- coding:utf-8 -*-

from django.shortcuts import render,HttpResponse,redirect

import time

from django.views.decorators.cache import cache_page

db = {

'alex': "asdfasdfasdasdfasdf",

'eirc': '11111111111',

}

def login(request):

if request.method == "POST":

username = request.POST.get('username')

pwd = request.POST.get('pwd')

if username == 'alex' and pwd == '123':

request.session['IS_LOGIN'] = True

request.session['USRNAME'] = 'alex'

return redirect('/app01/home/')

elif username == 'eirc' and pwd == '123':

request.session['IS_LOGIN'] = True

request.session['USRNAME'] = 'eirc'

return redirect('/app01/home/')

return render(request, 'login.html')

def home(request):

is_login = request.session.get('IS_LOGIN', False)

if is_login:

print request.session,type(request.session)

username = request.session.get('USRNAME', False)

data = db[username]

# return HttpResponse(data)

return render(request, 'home.html', {'username': username})

else:

return redirect("/app01/login/")

def logout(request):

# del request.session['IS_LOGIN']

# del reques

from django.contrib.sessions.backends.db import SessionStore

# print request.session._session_key

del request.session['IS_LOGIN']

request.session.delete(request.session._session_key)

return redirect('/app01/login/')

@cache_page(60 * 15)

def cache_page(request):

current = str(time.time())

return HttpResponse(current)

def index(request):

raise Exception('bb')

return HttpResponse('ok')

#

# def user_list(request, nid, page):

# print nid,page

# return HttpResponse(nid+page)

def user_list(request, v2, v1):

print v1,v2

return HttpResponse(v1+v2)

app01/urls.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from django.conf.urls import include, url

from django.contrib import admin

from app01 import views

urlpatterns = [

url(r'index/$', views.index),

url(r'cache/$', views.cache_page),

url(r'login/$', views.login),

url(r'home/$', views.home),

url(r'logout/$', views.logout),

]

Middleware/middle1.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from django.shortcuts import HttpResponse

class mmm(object):

def process_request(self,request):

print "mmm.process_request"

def process_view(self, request, callback, callback_args, callback_kwargs):

print "mmm.process_view"

def process_response(self, request, response):

print "mmm.process_response"

return response

def process_exception(self, request, exception):

print "擦了,下面那个中间件不管,那就我管吧"

return HttpResponse("擦了,下面那个中间件不管,那就我管吧")

class xxx(object):

def process_request(self,request):

print "xxx.process_request"

def process_view(self, request, callback, callback_args, callback_kwargs):

print "xxx.process_view"

def process_response(self, request, response):

print "xxx.process_response"

return response

def process_exception(self, request, exception):

print "View中出错了,但是我就不管"

return HttpResponse('ooooo')

Template/login.html

Template/index.html

.header{

height: 48px;

}

{{ username }}

缓存

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

一、配置settings.py

CACHES = {

'default': {

'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',

'LOCATION': os.path.join(BASE_DIR, 'cache'),

'TIMEOUT': 600,

'OPTIONS': {

'MAX_ENTRIES': 1000

}

}

}

2、应用

from django.shortcuts import render, HttpResponse

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)

def func(request):

return HttpResponse('xxx')

更多:

https://docs.djangoproject.com/en/1.9/topics/cache/

http://djangobook.py3k.cn/2.0/chapter15/

cookie和session >>> 用户登录验证、注销

一、操作Cookie

获取cookie:request.COOKIES[key]

设置cookie:response.set_cookie(key,value)

由于cookie保存在客户端的电脑上,所以,jquery也可以操作cookie。

$.cookie("list_pager_num", 30,{ path: '/' });

二、操作Session

获取session:request.session[key]

设置session:reqeust.session[key] = value

删除session:del request[key]

request.session.set_expiry(value)

* 如果value是个整数,session会在些秒数后失效。

* 如果value是个datatime或timedelta,session就会在这个时间后失效。

* 如果value是0,用户关闭浏览器session就会失效。

* 如果value是None,session会依赖全局session失效策略。

更多见:

https://docs.djangoproject.com/en/1.9/topics/http/sessions/

http://docs.30c.org/djangobook2/chapter14/

https://docs.djangoproject.com/en/1.9/ref/settings/#settings-sessions

三、应用

def login(func):

def wrap(request, *args, **kwargs):

# 如果未登陆,跳转到指定页面

if request.path == '/test/':

return redirect('http://www.baidu.com')

return func(request, *args, **kwargs)

return wrap

PS:

cookie: 保存于本机  ===》 本地某个目录下的文件

session: 保存于服务器

数据库同步:

python manage.py makemigrations

python manage.py migrate

request.session.get('k1')

request.session['k1'] = 'v1'

默认过期时间:2周

自定义设置:settings.py

总结:

session

用来保存用户会话信息,依赖于cookie

超时时间:写入cookie时,设置一个超时时间

Form(*)

django中的Form一般有两种功能:

1、用户提交数据验证

2、生成html标签

前端JS表单验证+后端验证 ====》 两套结合使用

Form

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import re

from django import forms

from django.core.exceptions import ValidationError

def mobile_validate(value):

mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')

if not mobile_re.match(value):

raise ValidationError('手机号码格式错误')

class PublishForm(forms.Form):

user_type_choice = (

(0, u'普通用户'),

(1, u'高级用户'),

)

user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,

attrs={'class': "form-control"}))

title = forms.CharField(max_length=20,

min_length=5,

error_messages={'required': u'标题不能为空',

'min_length': u'标题最少为5个字符',

'max_length': u'标题最多为20个字符'},

widget=forms.TextInput(attrs={'class': "form-control",

'placeholder': u'标题5-20个字符'}))

memo = forms.CharField(required=False,

max_length=256,

widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3}))

phone = forms.CharField(validators=[mobile_validate, ],

error_messages={'required': u'手机不能为空'},

widget=forms.TextInput(attrs={'class': "form-control",

'placeholder': u'手机号码'}))

email = forms.EmailField(required=False,

error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},

widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

View

def publish(request):

ret = {'status': False, 'data': '', 'error': '', 'summary': ''}

if request.method == 'POST':

request_form = PublishForm(request.POST)

if request_form.is_valid():

request_dict = request_form.clean()

print request_dict

ret['status'] = True

else:

error_msg = request_form.errors.as_json()

ret['error'] = json.loads(error_msg)

return HttpResponse(json.dumps(ret))

扩展:ModelForm

在使用Model和Form时,都需要对字段进行定义并指定类型,通过ModelForm则可以省去From中字段的定义

class AdminModelForm(forms.ModelForm):

class Meta:

model = models.Admin

#fields = '__all__'

fields = ('username', 'email')

widgets = {

'email' : forms.PasswordInput(attrs={'class':"alex"}),

}

总结:

1、创建类(forms.Form)

2、页面根据类的对象自动创建html标签

3、提交,request.POST

封装到一个类的对象里 obj

= UserInfo(request.POST)

4、用户输入是否合法

obj.is_valid

5、 只要有不合法

obj.errors

DEMO

Settings.py

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production

# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = 'dgwet1wf#!wo)cr1_y0tpxx5txvxug-upi2$&@n_ojq66pyl2a'

# SECURITY WARNING: don't run with debug turned on in production!

DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = (

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'app01',

)

MIDDLEWARE_CLASSES = (

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

#'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.auth.middleware.SessionAuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

'django.middleware.security.SecurityMiddleware',

)

ROOT_URLCONF = 's11day18_form.urls'

TEMPLATES = [

{

'BACKEND': 'django.template.backends.django.DjangoTemplates',

'DIRS': [os.path.join(BASE_DIR, 'templates')],

'APP_DIRS': True,

'OPTIONS': {

'context_processors': [

'django.template.context_processors.debug',

'django.template.context_processors.request',

'django.contrib.auth.context_processors.auth',

'django.contrib.messages.context_processors.messages',

],

},

},

]

WSGI_APPLICATION = 's11day18_form.wsgi.application'

# Database

# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

}

# Internationalization

# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS =(

os.path.join(BASE_DIR, "static"),

)

TEMPLATE_DIRS = (

os.path.join(BASE_DIR, 'templates'),

Urls.py

from django.conf.urls import include, url

from django.contrib import admin

from app01 import views

urlpatterns = [

url(r'^admin/', include(admin.site.urls)),

url(r'^user_list/$', views.user_list),

url(r'^ajax_data/$', views.ajax_data),

url(r'^ajax_data_set/$', views.ajax_data_set),

]

app01/views.py

#coding:utf-8

from django.shortcuts import render

# Create your views here.

from django import forms

from django.core.exceptions import ValidationError

import re

from django.shortcuts import HttpResponse

def mobile_validate(value):

mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')

if not mobile_re.match(value):

raise ValidationError('手机号码格式错误')

class UserInfo(forms.Form):

user_type_choice = (

(0, u'普通用户'),

(1, u'高级用户'),

)

user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,

attrs={'class': "form-control"}))

email = forms.EmailField(error_messages={'required': u'邮箱不能为空'})

host = forms.CharField(error_messages={'required': u'主机不能为空'})

port = forms.CharField(error_messages={'required': u'端口不能为空'})

mobile = forms.CharField(validators=[mobile_validate, ],

error_messages={'required': u'手机不能为空'},

widget=forms.TextInput(attrs={'class': "form-control",

'placeholder': u'手机号码'}))

memo = forms.CharField(required=False,

widget=forms.Textarea(attrs={'class': "form-control",

'placeholder': u'备注'})

)

def user_list(request):

obj = UserInfo()

if request.method == "POST":

user_input_obj = UserInfo(request.POST)

if user_input_obj.is_valid():

data = user_input_obj.clean()

print data

else:

error_msg = user_input_obj.errors.as_data()

return render(request, 'user_list.html', {'obj': user_input_obj, 'errors': error_msg})

return render(request, 'user_list.html', {'obj': obj})

#

# host = request.POST.get('host')

# port = request.POST.get('port')

# email = request.POST.get('email')

# mobile = request.POST.get('mobile')

# 输入不能为空,()

# email = 7676767675765

# mobile = 7676767675765

# ip = 7676767675765

def ajax_data(request):

print request.POST

return HttpResponse('ok')

import json

def ajax_data_set(request):

ret = {'status': True, 'error':""}

try:

print request.POST

except Exception,e:

ret['status'] = False

ret['error'] = str(e)

return HttpResponse(json.dumps(ret))

app01/templatetags/form_tag.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from django import template

from django.utils.safestring import mark_safe

from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

from django import template

from django.utils.safestring import mark_safe

from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

@register.simple_tag

def error_message(arg):

if arg:

return arg[0][0]

else:

return ''

Templates/user_list.html

{% load form_tag %}

.form-control{

background-color: red;

}

用户类型:{{ obj.user_type }}

{% error_message errors.user_type %}

主机:{{ obj.host }}

{% error_message errors.host %}

端口:{{ obj.port }} {{ errors.port }}

邮箱:{{ obj.email }} {{ errors.email }}

手机:{{ obj.mobile }} {{ errors.mobile }}

备注:{{ obj.memo }} {{ errors.memo }}

主机名端口

1.1.1.199991.1.1.29998

function AjaxSubmit(){

var host = "1.1.1.1";

var port = "9999";

$.ajax({

url: "/ajax_data/",

type: 'POST',

data: {h:host, p:port},

success: function(arg){

}

});

}

function AjaxSubmitSet(){

var array_users= [

{'username': 'alex', 'age': 18},

{'username': 'rain', 'age': 16},

{'username': 'eric', 'age': 17}

];

$.ajax({

url: "/ajax_data_set/",

type: 'POST',

tradition: true,

data: {data: JSON.stringify(array_users)},

success: function(arg){

// json.loads

var callback_dict = $.parseJSON(arg);

if(callback_dict.status){

alert('成功');

}else{

alert(callback_dict.error);

}

}

});

}

Ajax(*)

一、简介

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

二、应用

1、普通表单

veiw中设置返回值:

returnrender_to_response('Account/Login.html',data,context_instance=RequestContext(request))

或者

returnrender(request, 'xxx.html', data)

html中设置Token:

{% csrf_token %}

2、Ajax

对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。

view.py

from django.template.context import RequestContext

# Create your views here.

def test(request):

if request.method == 'POST':

print request.POST

return HttpResponse('ok')

return render_to_response('app01/test.html',context_instance=RequestContext(request))

text.html

{% csrf_token %}

var csrftoken = $.cookie('csrftoken');

function csrfSafeMethod(method) {

// these HTTP methods do not require CSRF protection

return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

}

$.ajaxSetup({

beforeSend: function(xhr, settings) {

if (!csrfSafeMethod(settings.type) && !this.crossDomain) {

xhr.setRequestHeader("X-CSRFToken", csrftoken);

}

}

});

function Do(){

$.ajax({

url:"/app01/test/",

data:{id:1},

type:'POST',

success:function(data){

console.log(data);

}

});

}

更多:https://docs.djangoproject.com/en/dev/ref/csrf/#ajax

参考博客:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值