第十九节

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')
python上传文件
<!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')
一个简单CBV的处理过程
<!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>
home.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名称如何变化,对应的表单不用再更改。
View Code

 

# 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/
View Code

 默认值

url(r'^index/', views.index, {'name': 'root'}),

def index(request,name):
    print(name)
    eturn HttpResponse('OK')
View Code

 

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/
View Code

 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
View Code

 

 二、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
View Code

 

 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)
View Code

 

 # 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')
View Code
from app01 import models
def orm(request):
    dic = {'username':'pan','password':'45645676'}
    models.UserInfo.objects.create(**dic)
    return HttpResponse('orm')
View Code
from app01 import models
def orm(request):
    obj = models.UserInfo(username='tao',password='547')
    obj.save()
    return HttpResponse('orm')
View Code

# 从数据库取所有数据

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
View Code

# 查询数据

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的数据
View Code

# 删除数据

models.UserInfo.objects.filter(username='marry').delete()
View Code

# 更新数据

models.UserInfo.objects.all().update(password='123456')

# 更新所有用户的密码
View Code

models字段的参数

 

 

 

 

 

 

 

 

 

##

posted @ 2018-01-14 10:37  酷酷的狐狸  阅读(212)  评论(0编辑  收藏  举报