【python】-- Django路由系統(網址關係映射)、視圖、模板

Django路由系統(網址關係映射)、視圖、模板

 

1、路由系統(網址關係映射)

一、單一路由對應:css

一個url對應一個視圖函數(類)html

urls.py:
url(r'^test', views.test), 
#url(r'^home', views.Test.as_view()),

views.py:
def test(request):
    print(request.method)
    return render(request, "home.html")
"""
class Test(View):

    def get(self, request):
        print(request.method)
        return render(request, "home.html")

    def post(self, request):
        print(request.method)
        return render(request, "home.html")
"""

  

 二、基於正則路由對應:python

多個url對應一個視圖jquery

urls.py
# 多個url對應一個視圖函數,不過在給視圖函數傳參時,要根據對應形參位置進行傳參
url(r'^detail-(\d+)-(\d+).html', views.detail),
# 多個url對應一個視圖函數,推薦這種寫法,在正則匹配完畢後進行了分組分配,在傳參時就能夠形參位置變化也沒有關係
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail),

views.py:
#普通傳參
def detail(request, nid, uid):
    print(nid, uid)
    return HttpResponse("%s - %s" % (nid, uid))
#args傳參
def detail(request, *args, **kwargs):
    print(args[0], args[1])
    return HttpResponse("%s - %s" % (args[0], args[1]))
#kwargs傳參
def detail(request, *args, **kwargs):
    print(kwargs["nid"], kwargs["uid"])
    return HttpResponse("%s - %s" % (kwargs["nid"], kwargs["uid"]))

 

三、name:shell

對URL路由關係進行命名,之後能夠根據此名稱生成本身想要的URLdjango

urls.py:
url(r'^url_1/', views.index, name='i1'),
url(r'^url_2/(\d+)/(\d+)/', views.index, name='i2'),
url(r'^url_3/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),
		
views.py:
from django.urls import reverse
def func(request, *args, **kwargs):
    url1 = reverse('i1')                              # url_1/
    url2 = reverse('i2', args=(1,2,))                 # url_2/1/2/
    url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # url_3/1/9/


xxx.html:
    
    {% url "i1" %}               # url_1/
    {% url "i2" 1 2 %}           # url_2/1/2/
    {% url "i3" pid=1 nid=9 %}   # url_3/1/9/

PS:
    # 顯示當前的URL
    request.path_info 

 

四、多級路由:session

多級路由目的避免有多個app時,在project urls.py的路由(網址)因路徑名稱一致而引發的衝突app

#project/urls.py:
    from django.conf.urls import url, include
    from django.contrib import admin
    urlpatterns = [
        url(r'^app1/', include("app1.urls")),
        url(r'^app2/', include("app2.urls")),
    ]

#app01/urls.py:
    from django.conf.urls import url
    from app1 import views
    urlpatterns = [
        url(r'^test', views.test),
    ]

#app02/urls.py:
    from django.conf.urls import url
    from app2 import views
    urlpatterns = [
        url(r'^test', views.test),
    ]

 

五、默認值ide

在路由關係映射的同時,添加額外參數,views.py中的對應函數可接受參數使用函數

#urls.py:
url(r'^test', views.url_test, {"value": 3}),

#views.py:
def url_test(request, value):
    print(value)
    return HttpResponse("OK")

 

六、命令空間

在project的urls.py中定義namespace後,在views中的函數會根據指定namespace生成url

6.1.、project.urls.py

from django.conf.urls import url, include


urlpatterns = [
    url(r'^app1/', include("app1.urls", namespace='name_1')),
    url(r'^app2/', include("app1.urls", namespace='name_2')),
]

6.二、app1.urls.py

from django.conf.urls import url
from app1 import views

app_name = "app1"  # 若是在project urls.py中定義namespace,那在這裏就要定義一下app_name

urlpatterns = [
    url(r'^test$', views.url_test, name='i1'),
]

6.三、app1.views.py

from django.shortcuts import reverse, HttpResponse


def url_test(request):
    url_1 = reverse("name_1:i1")
    url_2 = reverse("name_2:i1")
    print(url_1, url_2)
    return HttpResponse("OK")

 

 

  

2、視圖

一、FBV&CBV

1.一、 FBV (Function Base VIew)在view(視圖)中基於函數編寫邏輯

#urls.py:
url(r'^test', views.test),  # FBV  function base view


#views.py:
def test(request):
    if request.method == "GET":
        return render(request, 'test.html')

1.二、CBV(Class Base Viev)在view(視圖)中基於類編寫邏輯

#urls.py;
url(r'^home', views.Test.as_view()),  # CBV  class base view   .as_view() Test沒有view因此在views.py中Test類中繼承Django的View


#views.py:
from django.views import View


class Test(View):

    # 調用父類中的dispatch方法,並重寫
    def dispatch(self, request, *args, **kwargs):  # 經過dispatch的反射能夠找到如:get、post方法的起始點
        print("before")
        result = super(Test, self).dispatch(request, *args, **kwargs)
        return result

    def get(self, request):
        print(request.method)
        return render(request, "home.html")

    def post(self, request):
        print(request.method)
        return render(request, "home.html")

 二、HTML from表單提交數據的提取示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/test" method="POST" enctype="multipart/form-data"><!--enctypes屬性沒有的話,默認提交的是字符串,沒法實現文件上傳-->
        <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="file"/>
        </p>

        <input type="submit" value="提交"/>
    </form>
</body>
</html>
test.html
def test(request):
    if request.method == "GET":
        return render(request, 'test.html')
    elif request.method == "POST":
        # text
        v = request.POST.get('pwd')   # 獲取input輸入框輸入的value
        print(v)
        # radio
        v0 = request.POST.get('gender')   # 獲取radio的value
        print(v0)
        # checkbox
        v1 = request.POST.getlist('favor')   # 獲取checkbox多選狀況下的value
        print(v1)
        # select
        v2 = request.POST.getlist('city')   # 獲取select下拉框multiple狀況下的value
        print(v2)
        # file
        obj = request.FILES.get('file')    # 獲取上傳文件並保存
        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():  # chunks()利用生成器,每次只加載部分上傳的文件,直至加載完畢
            f.write(i)
        f.close()
        return redirect("/test")
    else:
        # PUT,DELETE,HEAD,OPTION...
        return redirect("/test")

三、查看views.py中的request封裝的信息

from django.core.handlers.wsgi import WSGIRequest
request.environ
request.environ['HTTP_USER_AGENT']

  

 

 3、模板

一、模板的特殊語言

 1 視圖中函數:
 2 def func(request):
 3     return render(request, "index.html", {'current_user': "QQ"})
 4 
 5 
 6 index.html:
 7 <html>
 8 ..
 9     <body>
10         <div>{{current_user}}</div>
11     </body>
12 </html>
變量名
 1 視圖函數:
 2 def func(request):
 3     return render(request, "index.html", {'current_user': "QQ", 'user_list': ['1', '2']})
 4 
 5 
 6 index.html:
 7 < html >
 8     ..
 9     < body >
10         < div > {{current_user}} < / div >
11         < ul >
12             { %for row in user_list %}   <!--for循環中嵌套if判斷>
13                 { % if row == "2" %}     <!--if判斷>
14                 < li > {{row}} < / li >
15                 { % endif %}             <!--結束if判斷>
16             { % endfor %}               <!--結束for循環>
17         < / ul >
18     < / body >
19 < / html >
for循環,if判斷
 1 視圖函數:
 2 def func(request):
 3                     return render(request, "index.html", {
 4                                 'current_user': "QQ", 
 5                                 'user_list': ['1','2'], 
 6                                 'user_dict': {'k1': 'v1', 'k2': 'v2'}})
 7 
 8 index.html:
 9 < html >
10     ..
11     < body >
12         <div>{{current_user}}</div>
13         <a> {{ user_list.1 }} </a>
14         <a> {{ user_dict.k1 }} </a>
15         <a> {{ user_dict.k2 }} </a>
16     < / body >
17 < / html >
18 
19 索引
索引
 1 試圖函數:
 2 USER_DICT = {
 3     "k1": "value1",
 4     "k2": "value2",
 5     "k3": "value3",
 6     "k4": "value4"
 7 }
 8 
 9 def for_dict(request):
10     return render(request, "index.html", {"user_dict": USER_DICT})
11 
12 index.html:
13 <!DOCTYPE html>
14 <html>
15 <head lang="en">
16     <meta charset="UTF-8">
17     <title></title>
18 </head>
19 <body>
20     <ul>
21         {%for key in user_dict.keys%}  <!--循環獲取key-->
22         <li>
23            {{key}}
24         </li>
25         {%endfor%}
26     </ul>
27     <ul>
28         {%for value in user_dict.values%} <!--循環獲取value-->
29         <li>
30            {{value}}
31         </li>
32         {%endfor%}
33     </ul>
34     <ul>
35         {%for key,value in user_dict.items%} <!--循環獲取key,value-->
36         <li>
37            {{key}}--{{ value }}
38         </li>
39         {%endfor%}
40     </ul>
41 </body>
42 </html>
43 
44 for循環字典
for循環字典
1 <!--表示當前循環的執行次數的整數計數器。這個計數器是從1開始的,因此在第一次循環時forloop.counter 將會被設置爲1-->
2 {% for item in todo_list %}
3 <p>{{ forloop.counter }}: {{ item }}</p>
4 {% endfor %}
5 
6 
7 ps:<!--forloop.counter0 相似於 forloop.counter ,可是它是從0計數的。第一次執行循環時這個變量會被設置爲0-->
forloop.counter
1 <!--布爾值類型,在第一次執行循環時該變量爲True-->
2 {% for object in objects %}
3 {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
4 {{ object }}
5 </li>
6 {% endfor %}
forloop.first
 1 <!--布爾值,在最後一次執行循環時被置爲True-->
 2 {% for link in links %}
 3     {{ link }}
 4     {% if not forloop.last %} 
 5     | 
 6     {% endif %}
 7 {% endfor %}
 8 
 9 #結果:
10 Link1 | Link2 | Link3 | Link4
forloop.last

二、模板的繼承

父模板:

<!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 %}  #  <!--定義CSS繼承位置-->
</head>
<body>
	<div class="pg-header">oms</div>  
	{%block content%}{%endblock%}       <!--定義內容繼承位置-->
	<script src="/static/jquery.js"></script>
	{%block js%}{%endblock%}            <!--定義JavaScript繼承位置-->
</body>
</html>

子模板:

{% extends 'master.html' %}                  <!--聲明繼承的文件-->

{% block title %}用戶管理{% endblock %}      <!--在繼承文件的頭部位置放入值-->

{% block content %}							 <!--在繼承文件的內容位置放入值-->
    <h1>用戶管理</h1>tou
    <ul>
        {% for i in u %}
            <li>{{ i }}</li>
        {% endfor %}
    </ul>

{% block css %}                              <!--在繼承文件的CSS位置放入本身特有的CSS-->
    <style>
        body{
            background-color: red;
        }
    </style>
{% endblock %}

{% block js %}                               <!--在繼承文件的CSS位置放入本身特有的js-->
    <script></script>
{% endblock %}

三、模板的引用

{% include 'tag.html' %}  <!--直接include想要導入的HTML文本-->

四、自定義simple_tag

Django提供的模板方法(相似於python的內置函數),以供咱們在使用模板的時候,更加方便的對數據進行操做。

{{ k1|lower }}  # 將全部字母都變爲小寫
{{ k1|first|upper }}  # 將首字母變爲大寫
{{ k1|truncatewords:"30" }}  # 取變量k1的前30個字符
{{ item.createTime|date:"Y-m-d H:i:s" }}    # 將時間轉爲對應格式顯示

固然Django提供的方法是有限的,沒法知足咱們全部的需求,這個時候就須要自定製更加符合咱們本身需求的方法(函數),步驟以下:

  • a.在settings中註冊APP
1 INSTALLED_APPS = [
2     'django.contrib.admin',
3     'django.contrib.auth',
4     'django.contrib.contenttypes',
5     'django.contrib.sessions',
6     'django.contrib.messages',
7     'django.contrib.staticfiles',
8     'app',
9 ]
settings.py中註冊app
  • b.在app下建立templatetags目錄(templatetags目錄名稱不可變)
  • c.在templatetags目錄下定義test.py文件(py文件名任意)
  • d.在test.py文件中定義自定製函數
1 from django import template
2 from django.utils.safestring import mark_safe  
3 
4 register = template.Library()  #建立建立template對象 register
5 
6 @register.simple_tag           #利用register中對象的simple_tagz函數裝飾自定義函數
7 def addition(a1,a2):
8     return a1 + a2
自定義函數
  • e.在模板中引用自定義方法(函數)
 1 {% load test %}              <!--導入剛剛定義的py文件名稱-->
 2 <!DOCTYPE html>
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <title></title>
 7 </head>
 8 <body>
 9     {% addition  2  5 %}   <!--導入剛剛定義的函數(方法),參數用空格隔開-->
10 </body>
11 </html>
在模板中引用方法

 五、自定義filter

步驟與自定義simple_tag步驟一致,只是在引用自定義函數中用的裝飾器和模板中的引用方式不一樣:

  • a、b、c、步驟一致
  • d.在test.py文件中定義自定製函數
1 from django import template
2 from django.utils.safestring import mark_safe  
3 
4 register = template.Library()  #建立建立template對象 register
5 
6 
7 @register.filter               #利用register中對象的filter函數裝飾自定義函數
8 def addition(a1,a2):
9     return a1 + str(a2)
自定義函數
  • e.在模板中引用自定義方法(函數)
 1 {% load test %}              <!--導入剛剛定義的py文件名稱-->
 2 <!DOCTYPE html>
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <title></title>
 7 </head>
 8 <body>
 9     {{ 2|addition:30 }}  <!--導入剛剛定義的函數(方法){{ 參數1|addition:參數2 }}-->
10 </body>
11 </html>
在模板中引用方法

 PS:自定義simple_tag和自定義filter的區別。

  • 自定義simple_tag裝飾的函數能夠傳入任意數量的參數,但自定filter只能傳入兩個參數(間接傳入多個參數辦法:就是將第二個參數經過"args1,args2,args3"的形式傳入,而後經過split()解析獲取)
  • 自定義simple_tag裝飾的函數不能用於模板if條件,但自定filter用於if條件
相關文章
相關標籤/搜索