Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。
基本配置
一、创建django程序
- 终端命令:django-admin startproject sitename
- IDE创建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、数据库
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而pyth
DATABASES
=
{
'default'
: {
'ENGINE'
:
'django.db.backends.mysql'
,
'NAME'
:
'dbname'
,
'USER'
:
'root'
,
'PASSWORD'
:
'xxx'
,
'HOST'
: '',
'PORT'
: '',
}
}
on3中还无此模块,所以需要使用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、单一路由对应
1
|
url(r '^index$' , views.index), |
2、基于正则的路由
1
2
|
url(r '^index/(\d*)' , views.index), url(r '^manage/(?P<name>\w*)/(?P<id>\d*)' , views.manage), |
3、添加额外的参数
1
|
url(r '^manage/(?P<name>\w*)' , views.manage,{ 'id' : 333 }), |
4、为路由映射设置名称
1
2
|
url(r '^home' , views.home, name = 'h1' ), url(r '^index/(\d*)' , views.index, name = 'h2' ), |
设置名称之后,可以在不同的地方调用,如:
- 模板中使用生成URL {% url 'h2' 2012 %}
- 函数中使用生成URL reverse('h2', args=(2012,)) 路径:django.urls.reverse
- Model中使用获取URL 自定义get_absolute_url() 方法
class NewType(models.Model): caption = models.CharField(max_length=16) def get_absolute_url(self): """ 为每个对象生成一个URL 应用:在对象列表中生成查看详细的URL,使用此方法即可!!! :return: """ # return '/%s/%s' % (self._meta.db_table, self.id) # 或 from django.urls import reverse return reverse('NewType.Detail', kwargs={'nid': self.id})
获取请求匹配成功的URL信息:request.resolver_match
5、根据app对路由规则进行分类
1
|
url(r '^web/' ,include( 'web.urls' )), |
6、命名空间
a. project.urls.py
1
2
3
4
5
6
|
from django.conf.urls import url,include urlpatterns = [ url(r '^a/' , include( 'app01.urls' , namespace = 'author-polls' )), url(r '^b/' , include( 'app01.urls' , namespace = 'publisher-polls' )), ] |
b. app01.urls.py
1
2
3
4
5
6
7
|
from django.conf.urls import url from app01 import views app_name = 'app01' urlpatterns = [ url(r '^(?P<pk>\d+)/$' , views.detail, name = 'detail' ) ] |
c. app01.views.py
1
2
3
|
def detail(request, pk): print (request.resolver_match) return HttpResponse(pk) |
以上定义带命名空间的url之后,使用name生成URL时候,应该如下:
- v = reverse('app01:detail', kwargs={'pk':11})
- {% url 'app01:detail' pk=12 pp=99 %}
django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。
模板
1、模版的执行
模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % 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 %} <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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/env python #coding:utf-8 from django import template from django.utils.safestring import mark_safe 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 文件名
1
|
{ % load xx % } |
d、使用simple_tag
1
2
|
{ % 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', )
今日内容总结
1. 路由
- 普通 /index/ def index(request):...
- 正则 /index/(\d+)/ def index(request,nid):...
- name
/index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf name='n1'
url = reverse('n1') # /index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf
/index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf/(\d+)/ name='n2'
url = reverse('n2',args=(11,))
# /index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf/11/
url = reverse('n2',args=(22,))
# /index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf/22/
/index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf/(?P<nid>\d+)/ name='n3'
url = reverse('n2',kwargs={'nid':22})
# /index/sdf/887sf/sfsdfsdf/sdfsdf/sdf/sdf/22/
- 路由分发,include
- namespace
2. 视图:
FBV&CBV
请求相关:
request:封装了7个常用功能
PS:django去读取Meta中的请求头相关信息时,HTTP_USER_AGENT = "asdfasdfasdf"
浏览器:User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
HTTP_USER_AGENT:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
# 业务逻辑
响应相关:
- HttpResponse
- render
- rediect # 只有响应头
3. cookie和session
cookie,是保存在客户端浏览器上的键值对,浏览器发送请求时候会自动携带。
session,
写:
"""
{
“沈俊杰的随机字符串”:{'id':1,'name':'俊杰'},
“王岩的随机字符串”:{'id':11},
“李向龙的随机字符串”:{'id':4},
“美凯的随机字符串”:{'id':6},
}
表:
session_key value
沈俊杰的随机字符串 asfasdfasdfasdfwer2342fszdfsdfs
1. 生成随机字符串
2. 把随机字符串写到客户端浏览器cookie中
3. 在内存中大字典写入:
{
随机字符串: {'id':用户id}
}
"""
request.session['id'] = obj.id
request.session['name'] = obj.name
读:
"""
1. 获取客户端cookie中的随机字符串
2. 如果有:
则获取 key 对应的值
否则 返回None
"""
user_id = request.session.get('id')
4. 模板引擎
a. 基本实用
{{k1}}
if
for
b. 模板中自定义函数
- 在已注册的app中创建一个名字叫 templatetags 文件夹
- 任意创建一个py文件
- 创建名字交 register 的Library类的对象
- 定义函数
from django.template import Library
register = Library()
# 调用示例:{{ "建超"|meikai:"晓梅,依米"}}
# 参数最多2
# 可以做if的条件
@register.filter
def meikai(a1,a2):
n1,n2 = a2.split(',')
data = "我的名字叫:%s,我喜欢%s和%s" %(a1,n1,n2)
return data
# 调用示例:{% wangyan 1 2 3 4 %}
# 参数无限制
# 无法做if条件
@register.simple_tag
def wangyan(a1,a2,a3,a4):
result = a1+a2+a3+a4
return result
- 使用
{% load xl %}
{{ "建超"|meikai:"晓梅,依米"}}
{% wangyan 1 2 3 4 %}
PS:注册app,推荐: 'app01.apps.App01Config'
5. 中间件
概念:
中间件是一个类
定义:
以后想要对所有的请求做统一操作时,用中间件。(几个例外)
只是对少量的视图函数做操作时,用装饰器。
任务:
1. 对用户请求记录日志
2. 用户登录验证(只有login)
梳理:
1. 类
- 继承MiddlewareMixin
- 两个方法
process_request
process_response,必须设置返回值
2. 应用中间件
MIDDLEWARE = [
...
'xxxx.md.M1',
]
3. 示例:
1. 对用户请求记录日志
2. 用户登录验证 (只有login)
3. 权限验证