django程序进阶
一、URL路由转发
# django的生命周期
1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中. 2. url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配, 一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了. 3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端. 4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.
1.django获取表单数据
<form action="/login/" method="POST" enctype="multipart/form-data"> <p> <input type="text" name="user" placeholder="用户名" /> </p> <p> <input type="password" name="pwd" placeholder="密码" /> </p> <p> 男:<input type="radio" name="gender" value="1"/> 女:<input type="radio" name="gender" value="2"/> 张扬:<input type="radio" name="gender" value="3"/> </p> <input type="submit" value="提交"/> </form>
# views.py def login(request): if request.method == "GET": return render(request,'login.html') elif request.method == "POST": v = request.POST.get("gender") # 获取单个值时采用get方法,如果模板类型为checkbox这种可多选类型,则可以用getlist获取多个值,返回值为一个列表。 print(v) return render(request,'login.html')
结果为你选中的gender所对应的value值。
2.上传文件
from django.shortcuts import render # Create your views here. from django.shortcuts import redirect from django.shortcuts import HttpResponse def login(request): if request.method == "GET": return render(request,'login.html') elif request.method == "POST": 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() return render(request,'login.html') else: return redirect('/index.html')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="POST" enctype="multipart/form-data"> <p> <input type="text" name="user" placeholder="用户名" /> </p> <p> <input type="password" name="pwd" placeholder="密码" /> </p> <p> 男:<input type="radio" name="gender" value="1"/> 女:<input type="radio" name="gender" value="2"/> 张扬:<input type="radio" name="gender" value="3"/> </p> <p> 男:<input type="checkbox" name="favor" value="11"/> 女:<input type="checkbox" name="favor" value="22"/> 张扬:<input type="checkbox" name="favor" value="33"/> </p> <p> <select name="city" multiple> <option value="sh">上海</option> <option value="bj">北京</option> <option value="tj">天津</option> </select> </p> <p> <input type="file" name="fafafa"/> </p> <input type="submit" value="提交"/> </form> </body> </html>
3.FBV & CBV
FBV: function base view
CBV: class base view
# urls.py urlpatterns = [ path('home/',views.Home.as_view()), ] # views.py from django.views import View class Home(View): # 先调用dispatch方法,将客户端发来的请求lower,再返回处理的结果,在此之间,可以对处理过程加工 def dispatch(self, request, *args, **kwargs): print("before") # 调用父类的反射方法 result = super(Home,self).dispatch(request,*args,**kwargs) print("after") return result def get(self,request): #客户端发来get请求后,处理get请求 print(request.method) # 返回html前,会先打印get字符串 return render(request,'home.html') def post(self,request): #客户端发来post请求后,处理post请求 print(request.method,"POST") # 返回html前,会先打印post字符串 return render(request,'home.html')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/home/" method="POST"> <input type="text" name="user"/> <input type="submit"> </form> </body> </html>
View方法所能处理的请求
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
1.url匹配规则
# views.py USER_DICT = { '1':{'name':'jack1','email':'123@123.com'}, '2':{'name':'jack2','email':'123@123.com'}, '3':{'name':'jack3','email':'123@123.com'}, '4':{'name':'jack4','email':'123@123.com'}, } def detail(request,nid): user_info = USER_DICT[nid] return render(request,'detail.html',{'user_dict':user_info}) # detail.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>详细信息</h1> <h6>用户名:{{ user_dict.name }}</h6> <h6>邮箱:{{ user_dict.email }}</h6> </body> </html> # urls.py urlpatterns = [ url('detail.html',views.detail), ] # 访问http://127.0.0.1:8000/cmdb/detail/?nid=4 # 通过get方法,提交不同的nid可以得到不同的结果
# urls.py # 匹配一整类的url,但会按形式参数的顺序传递 url('detail-(d+).html',views.detail), # 只匹配整数 # urls.py # 准确的将值传递给相应变量,不会考虑传递顺序 url('detail-(?P<pid>d+)-(?P<nid>d+).html',views.detail), # views.py def detail(request,nid,pid): user_info = USER_DICT[nid] return render(request,'detail.html',{'user_dict':user_info})
2.url的灵活命名
# urls.py url('afdsgfdsfdg/',views.index,name='indexx'), # viewes.py def index(request): return render(request,'index.html') # index.html <form action="{% url 'indexx' %}" method="POST"> <input type="text" name="user"/> <input type="submit"> </form> # 无论url名称如何变化,对应的表单不用再更改。
# urls.py url('afdsgfdsfdg/',views.index,name='indexx'), # viewes.py def index(request): return render(request,'index.html') # index.html <form action="{% url 'indexx' % 3}" method="POST"> #这里随意加上一个数字,代表url后面可以加上任意数字匹配 <input type="text" name="user"/> <input type="submit"> </form> # 假设你访问的为afdsgfdsfdg/7/,服务器会正常返回,但内部返回的是afdsgfdsfdg/3/,浏览器的url看到的仍然是afdsgfdsfdg/7/ ------------------------------------------------------------------------------- # 正确返回客户请求的url <form action="{{ request.path_info }}" method="POST"> <input type="text" name="user"/> <input type="submit"> </form> # 假设你访问的为afdsgfdsfdg/7/,服务器会正常返回,并且内部返回的是afdsgfdsfdg/7/,浏览器的url看到的仍然是afdsgfdsfdg/7/
默认值
url(r'^index/', views.index, {'name': 'root'}), def index(request,name): print(name) eturn HttpResponse('OK')
reverse内部强制定制url
# urls.py url(r'^gfdsgdh/',views.index,name='i1'), url(r'^gfdsgdh/(d+)/(d+)/',views.index,name='i2'), url(r'^gfdsgdh/(?P<pid>d+)/(?P<nid>d+)/',views.index,name='i3'), # views.py def func(): from django.urls import reverse url1 = reverse('i1') # gfdsgdh/ url2 = reverse('i2',args = (1,2,)) # gfdsgdh/1/2/ url3 = reverse('i3',kargs = {'pid':1 ,'nid':9}) # gfdsgdh/1/9/ # xxx.html {% url "i1" %} # gfdsgdh/ {% url "i2" 1 2 %} # gfdsgdh/1/2/ {% url "i2" pid=1 nid=3 %} # gfdsgdh/1/9/
reverse通过别名返回url
# urls.py (django下的总url) /admin/ include('app01.urls',namespace='m1') /crm/ include('app01.urls',namespace='m2') # urls.py (app下的url) /index/ name = 'n1' # views.py v = reverser('m1:n1') print(v) 结果:/admin/index
二、ORM
1.orm基本配置
1.基本设置
# django默认使用sqlite,需要更改配置文件
# settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django1', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '192.168.31.36', 'PORT': '3306', } } INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', #django会查找app01下的models.py,创建数据库表 ] # 执行命令,数据库生成表 python manager.py makemmigrations python manager.py migrate
2.创建数据库表
# app01 models.py
from django.db import models # Create your models here. class UserInfo(models.Model): # 自动创建id列,自增 # 创建数据列,类型以及长度 username = models.CharField(max_length=32) password = models.CharField(max_length=64)
# django默认使用MySQLdb连接mysql,更改数据库为mysql,需要更改project同名文件夹下的__init__文件
import pymysql
pymysql.install_as_MySQLdb()
2.orm操作
# 创建数据
from app01 import models def orm(request): models.UserInfo.objects.create( username='marry',password='456' ) return HttpResponse('orm')
from app01 import models def orm(request): dic = {'username':'pan','password':'45645676'} models.UserInfo.objects.create(**dic) return HttpResponse('orm')
from app01 import models def orm(request): obj = models.UserInfo(username='tao',password='547') obj.save() return HttpResponse('orm')
# 从数据库取所有数据
from app01 import models def orm(request): result = models.UserInfo.objects.all() # result为QuerySet,一个object列表 print(result) for row in result: print(row.id,row.username,row.password) return HttpResponse('orm') # <QuerySet [<UserInfo: UserInfo object (1)>, <UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>, <UserInfo: UserInfo object (4)>, <UserInfo: UserInfo object (5)>, <UserInfo: UserInfo object (6)>]> 1 jack 123 2 tom 123 3 marry 456 4 marry 456 5 marry 456
# 查询数据
from app01 import models def orm(request): result = models.UserInfo.objects.filter(username='pan') for row in result: print(row.id,row.username,row.password) return HttpResponse('orm') # 查询数据库中username为pan的数据
# 删除数据
models.UserInfo.objects.filter(username='marry').delete()
# 更新数据
models.UserInfo.objects.all().update(password='123456') # 更新所有用户的密码
models字段的参数
##