Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。
基本配置
一、创建django程序
终端命令:django-admin startproject projectname
IED创建django程序时本质上都是自动执行上述命令
其他常用命令:
python manage.py runserver 0.0.0.0
python manage.py startapp appname
python manage.py syncdb
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
二、配置文件
1、数据库
1
2
3
4
5
6
7
8
9
10
11
|
DATABASES = {
'default' : {
'ENGINE' : 'django.db.backends.mysql' ,
'NAME' : 'dbname' ,
'USER' : 'root' ,
'PASSWORD' : 'xxx' ,
'HOST' : '',
'PORT' : '',
}
}
|
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
# 如下设置放置的与project同名的配置的 __init__.py文件中
import pymysql
pymysql.install_as_MySQLdb()
2、模版
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
)
3、静态文件
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
路由系统
1、每个路由规则对应一个view中的函数
url(r'^index/(\d*)', views.index),
url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),
url(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),
2、根据app对路由规则进行一次分类
url(r'^web/',include('web.urls')),
django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。
模板
1、模板的执行
模板的创建过程,对于模板,其实就是读取模板(其中嵌套这模板标签),然后将Model中获取的数据插入到模板中,最后将信息返回给用户
1
2
3
4
|
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
|
1
2
3
4
|
from django import template
t = template.Template( 'My name is {{ name }}.' )
c = template.Context({ 'name' : 'Adrian' })
print t.render(c)
|
1
2
3
4
5
6
7
8
9
10
|
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
|
1
2
3
4
5
6
7
8
9
10
|
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)
|
1
|
return render_to_response( 'Account/Login.html' ,data,context_instance = RequestContext(request))
|
2、模版语言
模板中也有自己的语言,该语言可以实现数据展示
` item `
{% for item in item_list %} <a>` item `</a> {% 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 = "<input type='text' id='%s' class='%s' />" %(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
1
2
3
4
5
6
7
8
9
|
INSTALLED_APPS = (
'django.contrib.admin' ,
'django.contrib.auth' ,
'django.contrib.contenttypes' ,
'django.contrib.sessions' ,
'django.contrib.messages' ,
'django.contrib.staticfiles' ,
'app01' ,
)
|
From表单
django的Form一般由两种功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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 '邮箱' }))
def __init__( self , * args, * * kwargs):
super (SampleImportForm, self ).__init__( * args, * * kwargs)
self .fields[ 'idc' ].widget.choices = models.IDC.objects. all ().order_by( 'id' ).values_list( 'id' , 'display' )
self .fields[ 'business_unit' ].widget.choices = models.BusinessUnit.objects. all ().order_by( 'id' ).values_list( 'id' , 'name' )
|
1
2
3
4
5
6
7
8
9
10
11
12
|
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中字段的定义
1
2
3
4
5
6
7
8
9
10
|
class AdminModelForm(forms.ModelForm):
class Meta:
model = models.Admin
fields = ( 'username' , 'email' )
widgets = {
'email' : forms.PasswordInput(attrs = { 'class' : "alex" }),
}
|
Model
到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:
创建数据库,设计表结构和字段
使用 MySQLdb 来连接数据库,并编写数据访问层代码
业务逻辑层去调用数据访问层执行数据库操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import MySQLdb
def GetList(sql):
db = MySQLdb.connect(user = 'root' , db = 'ucodedb' , passwd = '1234' , host = 'localhost' )
cursor = db.cursor()
cursor.execute(sql)
data = cursor.fetchall()
db.close()
return data
def GetSingle(sql):
db = MySQLdb.connect(user = 'root' , db = 'ucodedb' , passwd = '1234' , host = 'localhost' )
cursor = db.cursor()
cursor.execute(sql)
data = cursor.fetchone()
db.close()
return data
|
django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM)。
PHP:activerecord
Java:Hibernate
C#:Entity Framework
django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表。
1、创建Model,之后可以根据Model来创建数据库表
from django.db import models
class userinfo(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
memo = models.TextField()
常用字段:
1、models.AutoField 自增列 = int(11)
如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField 字符串字段
必须 max_length 参数
3、models.BooleanField 布尔类型=tinyint(1)
不能为空,Blank=True
4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
继承CharField,所以必须 max_lenght 参数
5、models.DateField 日期类型 date
对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField 日期类型 datetime
同DateField的参数
7、models.Decimal 十进制小数类型 = decimal
必须指定整数位max_digits和小数位decimal_places
8、models.EmailField 字符串类型(正则表达式邮箱) =varchar
对字符串进行正则表达式
9、models.FloatField 浮点类型 = double
10、models.IntegerField 整形
11、models.BigIntegerField 长整形
integer_field_ranges = {
'SmallIntegerField': (-32768, 32767),
'IntegerField': (-2147483648, 2147483647),
'BigIntegerField': (-9223372036854775808, 9223372036854775807),
'PositiveSmallIntegerField': (0, 32767),
'PositiveIntegerField': (0, 2147483647),
}
12、models.IPAddressField 字符串类型(ip4正则表达式)
13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
参数protocol可以是:both、ipv4、ipv6
验证时,会根据设置报错
14、models.NullBooleanField 允许为空的布尔类型
15、models.PositiveIntegerFiel 正Integer
16、models.PositiveSmallIntegerField 正smallInteger
17、models.SlugField 减号、下划线、字母、数字
18、models.SmallIntegerField 数字
数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField 字符串=longtext
20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField 字符串,地址正则表达式
22、models.BinaryField 二进制
23、models.ImageField 图片
24、models.FilePathField 文件
常用字段的参数
1、null=True
数据库中字段是否可以为空
2、blank=True
django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
auto_now 自动创建---无论添加或修改,都是当前操作的时间
auto_now_add 自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
(u'M', u'Male'),
(u'F', u'Female'),
)
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default 默认值
8、verbose_name Admin中字段的显示名称
9、name|db_column 数据库中的字段名称
10、unique=True 不允许重复
11、db_index = True 数据库索引
12、editable=True 在Admin里是否可编辑
13、error_messages=None 错误提示
14、auto_created=False 自动创建
15、help_text 在Admin中提示帮助信息
16、validators=[]
17、upload-to
实现功能
①实现文件上传
home.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def upload(request):
if request.method = = "POST" :
inp_post = request.POST
print inp_post
inp_files = request.FILES
print inp_files
file_obj = inp_files.get( "file_name1" )
f = open (file_obj.name, 'wb' )
for line in file_obj.chunks():
f.write(line)
f.close()
return render(request, 'home/upload.html' )
|
upload.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< title ></ title >
</ head >
< body >
< form action = "/upload/" method = "POST" enctype = "multipart/form-data" >
< p >< input type = "file" name = "file_name1" /></ p >
< p >< input type = "text" name = "filename" /></ p >
< input type = "submit" value = "Upload" />
</ form >
</ body >
</ html >
|
url.py
1
2
3
4
5
6
7
8
|
from django.conf.urls import url
from django.contrib import admin
from app01.views import account
from app01.views import home
urlpatterns = [
url(r 'login/' ,account.login ),
url(r 'index/' ,home.index ),
url(r 'upload/' ,home.upload ),
|
Form表单中的CharField字段
1
2
3
4
5
6
7
8
9
10
|
__author__ = 'ryan'
from django import forms
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget = forms.PasswordInput())
|
models中的CharField字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
from __future__ import unicode_literals
from django.db import models
class UserInfo(models.Model):
USER_TYPE_LIST = (
( 1 , "F" ),
( 2 , "M" ),
)
name = models.CharField(max_length = 32 ,primary_key = True )
user_type = models.IntegerField(choices = USER_TYPE_LIST,default = 1 )
ctime = models.DateTimeField(auto_now = True )
uptime = models.DateTimeField(auto_now_add = True )
email = models.EmailField(max_length = 32 ,null = True )
email_default = models.EmailField(max_length = 32 ,default = "admin@163.com" )
ip = models.GenericIPAddressField(protocol = 'both' ,null = True ,blank = True )
img = models.ImageField(null = True ,blank = True ,upload_to = "upload" )
def __unicode__( self ):
return self .name
|
两个模块中的charField等字段的区别说明:
forms跟数据库没有关系,当用户发送过来请求的时候,forms只用来验证用户输入的合法性,
即返回给用户的结果(提示)要么是正确的要么是错误,换句话说forms验证用户输入是否合法,
返回给用户的信息就是用户本次输入合法与否
models.xxx只用来控制数据库的创建,对于django框架,如果没有后台管理功能,则不会出现如下的models.xxxx类型的字段,
只会存在基本的几种类,比如布尔、浮点型、整型、字符串类型等基本的几种数据类型,也就是我们常说的Python基本数据类型
本文转自027ryan 51CTO博客,原文链接:http://blog.51cto.com/ucode/1864640,如需转载请自行联系原作者