Django基础篇
Django是WEB框架的一种,相对于其他的WEB框架(如Tornado、Flash、Bottle)的优势为:大而全,框架本身集成了数据库操作的ORM、模型绑定、模板引擎、Session、缓存等功能。
如何配置一个简单的Django程序:
一、创建一个django程序
可以通过终端创建,也可以通过编程工具PyCharm来创建
- 终端创建:django-admin startproject sitename
- 编程工具创建:File--->>New Project 本质上还是调用上面的命令创建
其他常用的命令还有:
#启动django程序 python manage.py runserver 0.0.0.0 #创建一个app python manage.py startapp appname #同步数据库 python manage.py syncdb #检查数据库并创建临时sql语句 python manage.py makemigrations #创建数据库或更新数据库 python manage.py migrate #对django程序的admin后台管理创建超级管理员 python manage.py createsuperuser
二、settings文件的配置:
1、数据库的配置
在pycharm创建的工程默认的settings中的数据库为sqlite,可以设置成生产环境总的mysql数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '',
}
}
但是这种mysql数据库配置只适合在python 2.x版本的可以使用,如果再python 3.x版本操作mysql数据库的话,仅仅这种配置就无法满足了,还应该在工程名下同工程名同名的文件夹下的__init__.py文件中添加如下代码:
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替 # 在与project同名的文件夹下的 __init__.py文件中配置 import pymysql pymysql.install_as_MySQLdb()
2、模板
如果settings中如果没有模板的配置,可以在其中添加如下代码,这样一些前端的html文件才可以被调用。
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
)
3、静态文件
这个一定要配置,因为一些静态文件(比如:css js等)要放在此目录下
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
路由系统
路由系统相当于中转枢纽,当客户发送url请求的时候,要经过路由系统转发到view处理,view处理操作数据库,对模板进行渲染返回给客户端。
1、单一路由
url(r'^index$', views.index),
这里的url(r'^index$',views.index)也可以这样写url(r'^index/$',views.index)index后加了一个反斜线/,那么在其他地方引用这个url的时候也要加上/,如果没有的/,那么其他应用的地方也应该没有。
2、基于正则路由
url(r'^index/(\d*)', views.index), url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),
注:这个url中带有参数,那么在view的对应的函数中也要加上参数如:
#url(r'^index/(\d*)', views.index),在view的对应的函数
def index(request,num):
pass
#url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),
def manage(request,name,id):
pass
3、url中添加额外的参数,这个参数作为view函数中参数的默认值
url(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),
view中对应的函数为:
def manage(request,id):
pass
4、为路由映射设置名称
url(r'^home', views.home, name='h1'), url(r'^index/(\d*)', views.index, name='h2'),
这个映射相当于给url起个别名,在模板中可以这样用:{% url 'h1' %} {% url 'h2' 123 %}
那么view中也可通过这个name来获取url,这就要用到reverse()方式在view中获取url
在url中定义的路径如下:
url(r'^asdfasdfasdf/', views.index, name='i1'), url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'), url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),
在view中获取url的方式为:
from django.urls import reverse
def func(request, *args, **kwargs):
url1 = reverse('i1')
url2 = reverse('i2', args=(1,2,))
url3 = reverse('i3', kwargs={'pid': 1, "nid": 9})
#那么通过reverse()生成的url分别为:
url1 = asdfasdfasdf/
url2 = yug/1/2/
url3 = buy/1/9/
在模板中使用
{% url "i1" %} # asdfasdfasdf/
{% url "i2" 1 2 %} # yug/1/2/
{% url "i3" pid=1 nid=9 %} # buy/1/9/
还有在模板中也可以使用request.path_info来获取当前路径 {{ request.path_info }}
5、根据app对路由规则进行分类(多级路由)
当程序中有多个app的话,如果在一个总的url中添加多个app对应的路径,这样在后期维护的时候就会很乱,而且不好操作。这样就可以在每个app下创建一个子url,配置如下:
#比如在CMDB app下创建一个子url
url(r'^cmdb/',include('cmdb.urls')),
django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。
模板
1、模板的执行过程
对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据通过模板语言插入到模版中,最后将信息渲染后返回给用户。
2、模板语言的书写方式:
#获取单一个值
{{ name }}
#获取对象内的值,如果对象是字典,用.健获取
{{ obj.name }}
#获取对象内的值,如果对象是列表,用.索引获取
{{ obj.0 }}
#for循环
{% for item in item_list %} <a>{{ item }}</a> {% endfor %}
#在for中可以使用一些方法
forloop.counter forloop.first forloop.last
#if...else判断
{% if 条件 %} {% else %} {% endif %}
#当然可以在for循环中套if,也可以在if中套for循环
3、自定义simple_tag或filter
(1)在app中创建templatetags模块
(2)创建任意 .py 文件,如:xx.py
#!/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)
如果是filter的话,定义如下。需要注意的是:定义的filter函数只能定义两个参数
@register.filter
def my_filter(v1,v2):
return v1 + v2
这里的mark_safe()方法,表示从后台传到前台的html字符串是安全的,非xss攻击,那么这个html字符串经过mark_safe()处理后前台便可安全将此html代码解析成可读状态。
(3)在使用自定义simple_tag或filter的html文件中导入之前创建的 xx.py 文件名
{% load xx %}
(4)使用simple_tag或filter
{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}
#使用filter的方式
{{ "goser"|my_filter:"is a good man" }}
(5)在settings中配置当前app,不然django无法找到自定义的simple_tag
使用simple_tag和filter的优缺点:
simple_tag:不能作为if条件,但参数可以任意多
filter:最多两个参数,不能加空格。但能作为if条件(比如在html模板中参见if判断的条件{% if "goser"|my_filter:"123" %}.......{% endif %})
4、模板的继承及include
定义母板master.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} {% endblock %}</title>
<link rel="stylesheet" href="/static/commons.css" />
<style>
.pg-header{
height: 50px;
background-color: seashell;
color: green;
}
</style>
{% block css %} {% endblock %}
</head>
<body>
<div class="pg-header">主机管理</div>
<div>
<a>asdf</a>
<a id="">asdf</a>
<a>asdf</a>
<a>asdf</a>
<a>asdf</a>
</div>
<script src='jquery-1.12.3.js'></script>
{% block js %} {% endblock %}
</body>
</html>
定义include模板tag.html
<li>{{ item }}</li>
让userinfo.html继承模板和include模板
{% extends 'master.html' %}
{% block title %}用户管理{% endblock %}
{% block content %}
<h1>用户管理</h1>
<ul>
{% for i in u %}
<li>{{ i }}</li>
{% endfor %}
</ul>
{% for i in u %}
{% include 'tag.html' %}
{% endfor %}
{% endblock %}
{% block css %}
<style>
body{
background-color: red;
}
</style>
{% endblock %}
{% block js %}
<script></script>
{% endblock %}
视图view
1、获取用户请求数据
#获取GET请求的数据 request.GET #获取用户POST方式提交的数据 request.POST #获取用户上传文件对象的方式 request.FILES
2、checkbox等多选的内容
#如果用户提交的数据是多选的,比如checkbox方式提交,那么在view中就要用到getlist()方式获取数据 request.POST.getlist()
3、上传文件的处理
def login(request):
if request.method == "GET":
return render(request, 'login.html')
elif request.method == "POST":
# radio
# v = request.POST.get('gender')
# print(v)
# v = request.POST.getlist('favor')
# print(v)
# v = request.POST.get('fafafa')
# print(v)
obj = request.FILES.get('fafafa')
print(obj,type(obj),obj.name)
import os
file_path = os.path.join('upload', obj.name)
f = open(file_path, mode="wb")
for i in obj.chunks():
f.write(i)
f.close()
from django.core.files.uploadedfile import InMemoryUploadedFile
return render(request, 'login.html')
else:
# PUT,DELETE,HEAD,OPTION...
return redirect('/index/')
这里的上传的文件对象obj,要用到它的name属性(表示文件的名称)和chunks()(对文件进行分片的持续上传)
4、关于view中的FBV CBV的书写方式
FBV的方式为:在view中以函数的方式处理前台发来的数据,在url中的方式为:url(r'^index/', views.index)
CBV的方式为:在view中以类的方式处理前台发来的数据,需要继承View类。在url中的体现按时为:url(r'^home/', views.Home.as_view())
CBV的示例如下:
from django.views import View
class Home(View):
def dispatch(self, request, *args, **kwargs):
# 调用父类中的dispatch
print('before')
result = super(Home,self).dispatch(request, *args, **kwargs)
print('after')
return result
def get(self,request):
print(request.method)
return render(request, 'home.html')
def post(self,request):
print(request.method,'POST')
return render(request, 'home.html')
在view中对可以用装饰器对用户登录做认证操作,这就要用cookie或session操作
def auth(func):
def inner(reqeust,*args,**kwargs):
v = reqeust.COOKIES.get('username111')
if not v:
return redirect('/login/')
return func(reqeust, *args,**kwargs)
return inner
@auth
def index(reqeust):
# 获取当前已经登录的用户
v = reqeust.COOKIES.get('username111')
return render(reqeust,'index.html',{'current_user': v})
中间件
在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。
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',
)
自定义中间件
上面的中间件是创建工程后默认的中间件,当然也可以自定义中间件
与mange.py在同一目录下的文件夹 middleware下的auth.py文件中的AuthMiddleware类
中间件中可以定义五个方法,分别是:
- process_request(self,request)
- process_view(self, request, callback, callback_args, callback_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
1、创建中间件类
这个类要继承MiddlewareMixin类,只有继承了这个类,自定义的类才可以使用中间件的方法,如process_request、process_view、process_response方法等。
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class Middleware1(MiddlewareMixin):
def process_request(self,request):
print('middleware1_request info....')
def process_view(self, request, view_func, view_func_args, view_func_kwargs):
print('middleware1_view info....')
def process_response(self, request, response):
print('middleware1_response info....')
return response
class Middleware2(MiddlewareMixin):
def process_request(self,request):
print('middleware2_request info....')
def process_view(self, request, view_func, view_func_args, view_func_kwargs):
print('middleware2_view info....')
def process_response(self, request, response):
print('middleware2_response info....')
return response
def process_exception(self, request, exception):
if isinstance(exception,ValueError):
return HttpResponse('出现异常》。。')
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',
'middleware.auth.AuthMiddleware1'
'middleware.auth.AuthMiddleware2'
)
那么注册号中间件AuthMiddlware1和AuthMiddlware2后,运行程序,那么在控制台输出结果的顺序为:
middleware1_request info.... middleware2_request info.... middleware1_view info.... middleware2_view info.... middleware2_response info.... middleware1_response info....
生命周期:
根据上面的中间件执行过程,下面来总结下django的生命周期是什么,如下图所示:

django后台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)
浙公网安备 33010602011771号