Django 视图,模板,路由规则

View 视图 (续)

1、获取用户请求数据
  request.GET
  request.POST
  request.FILES

2、checkbox等多选的内容
request.POST.getlist()

3、上传文件
#  form标签做特殊设置 enctype="multipart/form-data"
obj = request.FILES.get('fn')
f = open(obj.name, mode='wb')
for item in obj.chunks():
  f.write(item)
  f.close()

对于<form>表单,django将 value提取到request.POST,将文件提取到 request.FILES 

示例:

复制代码
# Create your views here.
import os
from django.shortcuts import render,HttpResponse,redirect

def register(request):
    if request.method == "GET":
        return render(request, 'login.html')
    elif request.method == "POST":
        # input 
        u = request.POST.get('user')
        p = request.POST.get('pwd')
        print(u,p)

        # radio
        g = request.POST.get('gender')
        print(g)

        # checkbox
        f = request.POST.getlist('favor')
        print(f)

        v = request.POST.get('fn')
        print(v)  # 打印出的是文件名
        obj = request.FILES.get('fn')
        print(obj,type(obj),obj.name)  # obj是django.core.files.uploadedfile.InMemoryUploadedFile 类的对象
        file_path = os.path.join('upload', obj.name)
        f = open(file_path, mode="wb")
        for i in obj.chunks():         # chunks 在InMemoryUploadedFile类中
            f.write(i)
        f.close()
        
        return render(request, 'login.html')
    else:
        # PUT,DELETE,HEAD,OPTION...
        return redirect('/index/')
复制代码
复制代码
<!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"/>
        </p>
        <p>
            football:<input type="checkbox"  name="favor" value="11"/>
            basketball :<input type="checkbox" name="favor" value="22"/>
        </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="fn"/>
        </p>

        <input type="submit" value="提交"/>
    </form>
</body>
</html>
复制代码

request.environ 

request.POST、request.GET、request.COOKIES 本质是获取request.environ中的值,request.environ 封装了所有用户请求信息,如需获取其他值通过request.environ 

复制代码
from django.core.handlers.wsgi import WSGIRequest
def index(request):
    print(type(request)) # 查看request属于哪个类         
    print(request.environ) 
    print(request.environ['HTTP_USER_AGENT']
    for k,v in request.environ.items():
        print(k,v)
    return HttpResponse('OK')
复制代码

 

FBV (function base view) & CBV (Class base view)

FBV (function base view)
# urls.py 
urlpatterns = [
  url(r'^url/', views.func),  # 函数名
]
# view.py
def func(request):
  ...

CBV (Class base view)

urlpatterns = [
url(r'^home/',views.Home.as_view()), # CBV固定用法, 执行类中指定的方法 
]

# views.py
from django.views import View
class Home(View):
  def dispatch(self, request, *args, **kwargs):
    result = super(Home,self).dispatch(request, *args, **kwargs)
    return result

  def func(self,request):
    ...

复制代码
# urls.py
urlpatterns = [
    url(r'^home/',views.Home.as_view()), # CBV固定用法
]

# views.py
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
  # 先执行dispatch,基于反射(getattr)找到相应的方法
    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')
复制代码

 

模板渲染 (续)

循环字典

复制代码
# views.py
USER_DICT = { 'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4', 'k5': 'v5', } return render(request, 'index.html', {'user_dict': USER_DICT})
复制代码

html

复制代码
<ul>
{% for k in user_dict.keys %}
    <li>{{k}}</li> 
{% enfor %}
</ul>
<ul>
{% for val in user_dict.values %}
    <li>{{val}}</li>
{% enfor %}
</ul>
<ul>
{% for k,row in user_dict.items %}
    <li>{{k}}-{{row}}</li>
{% enfor %}
</ul>
复制代码

示例:查看详细  http:127.0.0.1:8000/detail/?nid=1 

复制代码
# Create your views here.
from django.shortcuts import render

USER_DICT = {
    '1': {'name': 'root1', 'email': 'root@live.com'},
    '2': {'name': 'root2', 'email': 'root@live.com'},
    '3': {'name': 'root3', 'email': 'root@live.com'},
    '4': {'name': 'root4', 'email': 'root@live.com'},
    '5': {'name': 'root5', 'email': 'root@live.com'},
}

def index(request):
    return render(request, 'index.html', {'user_dict': USER_DICT})

def detail(request):
    nid = request.GET.get('nid')
    detail_info = USER_DICT[nid]
    return render(request, 'detail.html', {'detail_info': detail_info})
复制代码
复制代码
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<ul>
    {% for k,row in user_dict.items %}
    <li>
        <a target="_blank" href="/datail/?nid={{ k }}">  {{row.name}} </a>
    </li>
    {% enfor %}
</ul>

</body>
</html>
复制代码
复制代码
<!-- detail.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>详细信息</h1>
    <h6>用户名:{{ detail_info.name }}</h6>
    <h6>邮箱:{{ detail_info.email }}</h6>
</body>
</html>   
复制代码

 

URL路由


静态路由
:一个url对应一个函数或类

url(r'^index/', views.index), 
url(r'^home/', views.Home.as_view()),   #CBV,继承view

动态路由:一类url对应一个函数

url(r'^detail-(\d+).html', views.detail),

示例:查看详细  http:127.0.0.1:8000/detail-1.html

复制代码
# Create your views here.
from django.shortcuts import render

USER_DICT = {
    '1': {'name': 'root1', 'email': 'root@live.com'},
    '2': {'name': 'root2', 'email': 'root@live.com'},
    '3': {'name': 'root3', 'email': 'root@live.com'},
    '4': {'name': 'root4', 'email': 'root@live.com'},
    '5': {'name': 'root5', 'email': 'root@live.com'},
}

def detail(request,nid):  # 直接从url中获取nid
    detail_info = USER_DICT[nid]
    return render(request, 'detail.html', {'detail_info': detail_info})    

def index(request):
    return render(request, 'index.html', {'user_dict': USER_DICT})
复制代码
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<ul>
    {% for k,row in user_dict.items %}
    <li>
        <a target="_blank" href="/datail-{{ k }}.html">  {{row.name}} </a>
    </li>
    {% enfor %}
</ul>

</body>
</html>
复制代码
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>详细信息</h1>
    <h6>用户名:{{ detail_info.name }}</h6>
    <h6>邮箱:{{ detail_info.email }}</h6>
</body>
</html>
复制代码

url(r'^detail-(\d+)-(\d+).html', views.detail),    

示例:http://127.0.0.1:8000/detail-2-9.html

复制代码
def detail(request,nid,uid): # 形参顺序固定不变
    #print(nid,uid)
    #return HttpResponse(nid)
    detail_info = USER_DICT[nid]
    return render(request, 'detail.html', {'detail_info': detail_info})    
或
def detail(request, *args,**kwargs): # 参数传递给*args
    pass   #  根据索引取值 args= (2,9)
复制代码

url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail),   (推荐使用分组)

复制代码
def detail(request,uid,nid):    # 形参顺序可以不固定
    #print(nid,uid)  
    #return HttpResponse(nid)
    detail_info = USER_DICT[nid]
    return render(request, 'detail.html', {'detail_info': detail_info})    
或
def detail(request, *args,**kwargs):  # 参数传递给**kargs
    pass  # 根据索引取值 kwargs = {'nid':1,'uid':3}
复制代码

url命名 (django 特有)

urlpatterns = [
  url(r'^xxx/', views.index, name='i1'),
]

<!-- 通过模板语言生成url -->
<form action="{% url 'i1' %}" method="POST">
    <p><input type="text" name="user" placeholder="用户名"></p>
    <p><input type="text" name="email"  placeholder="邮箱"/></p>
    <p><input type="submit" value="添加" /></p> 
</form>
复制代码
# 通过视图函数生成url
from django.urls import reverse
def index(request,nid): 
    print(request.path_info)  # /xxx
    V = reverse('i1')
    print(V)  # /xxx/
    return render(request, 'index.html', {'v': V,'user_dict': USER_DICT})   
复制代码

urlpatterns = [
  url(r'^xxx/(\d+)/', views.index, name='i2'), 
]

复制代码
<!-- 通过模板语言生成url -->
<form action="{% url 'i2' 2 %}" method="POST">   
    <p><input type="text" name="user" placeholder="用户名"></p>
    <p><input type="text" name="email"  placeholder="邮箱"/></p>
    <p><input type="submit" value="添加" /></p> 
</form> 

访问结果:http://127.0.0.1:8000/xxx/1 => <form action="/xxx/2" method="POST"> 
应用:进行某种操作后跳转回指定页面

<form action="{{ request.path_info }}" method="POST">  
    <p><input type="text" name="user" placeholder="用户名"></p>
    <p><input type="text" name="email"  placeholder="邮箱"/></p>
    <p><input type="submit" value="添加" /></p> 
</form> 

访问结果:http://127.0.0.1:8000/xxx/1 => <form action="/xxx/1" method="POST">
应用:进行某种操作后仍然在当前页面

复制代码

urlpatterns = [
  url(r'^xxx/(\d+)/(\d+)/', views.index, name='i3'), 
]

<!-- 通过模板语言生成url -->
<form action="{% url 'i3' 1 3 %}" method="POST">   
    <p><input type="text" name="user" placeholder="用户名"></p>
    <p><input type="text" name="email"  placeholder="邮箱"/></p>
    <p><input type="submit" value="添加" /></p> 
</form> 
复制代码
# 通过视图函数生成url
def index(request,nid): 
    print(request.path_info)  # /xxx/1/2/
    from django.urls import reverse
    V = reverse('i3',args=(90,91,))
    print(V)  # /xxx/90/91/  
    return render(request, 'index.html', {'v': V,'user_dict': USER_DICT})   
复制代码

urlpatterns = [
  url(r'^xxx/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i4'),
]

<!-- 通过模板语言生成url -->
<form action="{% url 'i4' nid=1 uid=3 %}" method="POST">   
    <p><input type="text" name="user" placeholder="用户名"></p>
    <p><input type="text" name="email"  placeholder="邮箱"/></p>
    <p><input type="submit" value="添加" /></p> 
</form> 
复制代码
# 通过视图函数生成url
def index(request,nid,uid):
    print(request.path_info)  # /xxx/1/2/
    from django.urls import reverse
    V = reverse('i4',kwargs={"nid":1, 'uid': '3'})
    print(V)  # /xxx/1/3/     
    return render(request, 'index.html', {'v': V,'user_dict': USER_DICT})  
复制代码

 

多级路由
根据请求不同的application进行路由分发,避免不同项目的url 冲突

proj/
├── proj/
│ ├── urls.py
├── app01/
│ ├── urls.py
├── app02/
│ ├── urls.py
└── manage.py

http://127.0.0.1:8000/cmdb/index 匹配 app01/urls.py的 index 

http://127.0.0.1:8000/monitor/index 匹配 app02/urls.py的 index 

复制代码
# proj/urls.py
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
    url(r'^cmdb/', include("app01.urls")),    #app01为cmdb的项目名
    url(r'^monitor/', include("app02.urls")),   #app02为monitor的项目名
]

# app01/urls.py
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
    url(r'^index/', views.login),
]

#  app02/urls.py
from django.conf.urls import url,include
from app02 import views
urlpatterns = [
    url(r'^index/', views.login),
]
复制代码


命名空间

不同的application使用同一个application下的url 

示例:

复制代码
# proj/urls.py            
urlpatterns = [
    url(r'^cmdb/', include('common.urls', namespace='u1')),
    url(r'^monitor/', include('common.urls', namespace='u2')),
]

# common/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from common import views
app_name = 'common'
urlpatterns = [
    url(r'^index/', views.index, name='index'),
]

# common/views.py
from django.shortcuts import render, HttpResponse,redirect
from django.urls import reverse

def index(request):
    v = reverse('author:index')
    print(v)

# 或使用模板语言
<form action="{% url 'author:index' %}" method="POST">
复制代码

 

默认值 -- 给视图函数传递一个参数

示例:

复制代码
# urls.py
urlpatterns = [
    url(r'^index/', views.index, {'name': 'xxx'}),
]

# views.py
def index(request,name):
    print(name)
    return HttpResponse('OK') 
复制代码
展开阅读全文

没有更多推荐了,返回首页