Django(二)路由系統、視圖、模板

大綱

1、內容概要: 
2、上節回顧 
3、Django 視圖–views 
  一、獲取用戶多個數據及文件上傳 
  二、FBV 和 CBV 
  三、裝飾器 
4、Django模板補充 
  - Django模板語言循環字典 
5、Django 路由系統 
  一、一對一:一個url對於一個函數或者一個類 
  2.一、一對多:一類url對應一個函數或者一個類 
  2.二、一對多,用法總結 
  三、name參數 
  四、url 路由分發機制 
  五、默認值 
  六、命名空間html

1、內容概要:

一、路由系統——urlspython

二、視圖web

三、模板正則表達式

四、ORM操做數據庫

​ select * from tb where id > 1django

​ # 對應關係app

​ models.tb.objects.filter(id__gt=1)框架

​ models.tb.objects.filter(id=1)函數

​ models.tb.objects.filter(id__lt=1)post

2、上節回顧

一、Django請求生命週期

  客戶端 -> URL對應關係(匹配) -> 視圖函數 -> 返回用戶字符串
  客戶端 -> URL對應關係(匹配) -> 視圖函數 -> 打開一個HTML文件,讀取內容

 

 

2.一、建立django projcet

django-admin startproject mysite
    ..
    mysite
        mysite
            - 配置文件
            - urls.py
            - settings.py

 

2.2建立django project app

cd mysite
python manage.py startapp cmdb

mysite
    mysite
        ……
    cmdb
        - views.py
        - admin.py
        - models.py # 建立數據庫表

 

三、配置

模板路徑
靜態文件路徑
# 註釋 CSRF

 

四、編寫程序

a. url.py
/index/    ->   func
 b. views.py
def func(request):
    # request:包含全部的請求數據
    ...
    return HttpResponse('字符串')  # 返回字符串
    return render(request, 'index.html', {''})  # 返回模板內容
    retrun redirect('URL')  # 返回url

c. 模板語言
return render(request, 'index.html', {'li': [11,22,33]})

{% for item in li %}  # 模板語音for循環
    <h1>{{item}}</h1>
{% endfor %}

***********  去索引:索引用點 **********
<h2> {{item[0] }} </h2>  # 不能這麼用,
<h2> {{item.0 }} </h2>   # 正確寫法

 

3、Django 視圖–views

一、獲取用戶多個數據及文件上傳

  • 一、獲取用戶請求數據
request.GET     # 獲取相應信息中get發送的數據
request.POST    # 獲取相應信息中post發送的數據
request.FILES   # 獲取相應信息中發送的文件數據
PS: # get和post都是日後臺發送數據,只是get信息在網址中,post信息包含着數據內,每每:
    GET:    # 獲取數據              
    POST:   # 提交數據
  • 二、checkbox等多選的內容
request.POST.getlist()  # get只能獲取一個值,像複選框、多選下拉框時,須要用getlist獲取
  • 三、上傳文件
# 上傳文件,form標籤作特殊設置  enctype="multipart/form-data"
obj = request.FILES.get('fafafa')  # 獲取上傳文件對象
print( obj.name )  # 上傳文件名稱
f = open(obj.name, mode='wb')
for item in obj.chunks():  # chunks():分塊,一點一點取數據(生成器、迭代器)
f.write(item)
f.close()

 

示例:用戶提交數據,後臺接收響應數據,並進行處理

工程名:mysite,app名:cmdb,建立接收用戶上傳數據目錄upload

mysite/urls.py

from django.contrib import admin
from cmdb import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
]

 

cmdb/views.py

from django.shortcuts import render, redirect,HttpResponse

def login(request):
    if request.method == "GET":
        return render(request, 'reg.html')
    elif request.method == "POST":
        # redio 單選框獲取
        redio = request.POST.get("gender")
        print("單選框的值:", redio)
        # checkbox 複選框獲取
        checkbox = request.POST.getlist("favor")
        print("複選框的值", checkbox)
        # 獲取文件數據
        obj = request.FILES.get("fafafa")
        print(obj, type(obj), obj.name)  # 打印文件信息
        import os
        file_path = os.path.join('upload', obj.name)
        with open (file_path, mode="wb") as f:
            for i in obj.chunks():
                f.write(i)
        return render(request, "reg.html")
    else:
        # PUT, DELETE, HEAD, OPTION……
        return redirect("/reg/")

 

templates/reg.html

<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>愛好:
            男:<input type="checkbox"  name="favor" value="11"/>
            女:<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="fafafa"/>
        </p>
        <input type="submit" value="提交"/>
    </form>
</body>

 

二、FBV 和 CBV

像這種urls.py裏匹配login,以後對應一個函數名。當匹配成功以後,就 執行views.py裏的這個函數,函數裏第一個參數封裝了全部的用戶請求信息。像這種叫FBV(function base view)

Django 裏面還有一種:CBV(class base view)

/index/ -> 函數名 
/index/ -> 類

 

上面都是FBV的方式,下面看看CBV寫法:

urls.py

url(r'^home/', views.Home.as_view()),  # CBV 固定用法

 

views.py

from django.views import View

class Home(View):  # 自定義的類必須繼承View
    # 重寫父類dispatch方法。程序定製時可使用
    # 父類的dispatch方法,查找get、post等方法,基於反射實現的。
    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)
        return render(request, "home.html")

    def post(self,request):  # 定義post方法,post請求執行這個方法
        print(request.method,"post方式")
        return render(request, "home.html")

 

home.html

<body>
    <form action="/home/" method="POST">
        <input type="text" name="user" />
        <input type="submit" />
    </form>
</body>

 

三、裝飾器

後續文章補充

4、Django模板補充

Django模板語言循環字典

urls.py

url(r'^index/', views.index),

views.py

USER_DICT = {
    'key1':{'name':'root1','eamil':'root@126.com'},
    'key2':{'name':'root2','eamil':'root@126.com'},
    'key3':{'name':'root3','eamil':'root@126.com'},
}
def index(request):
    return render(request, 'index.html', {'user_dict': USER_DICT})

 

index.html

<body>
    {{ user_dict.k1 }}
    <ul>
    {#  for row in user_dict # 默認循環顯示的是key  #}
        {% for k in user_dict.keys %}  {# 循環字典:取key值 #}
            <li>{{ k }}</li>
        {% endfor %}
    </ul>
    <ul>
        {% for val in user_dict.values %}  {# 循環字典:取value值 #}
            <li>{{ val }}</li>
        {% endfor %}
    </ul>
    <ul>
        {% for k,row in user_dict.items %}  {# 循環字典:取key、value #}
            <li>{{ k }}-{{ row }}</li>
        {% endfor %}
    </ul>
</body>

 

5、Django 路由系統

一、一對一:一個url對於一個函數或者一個類

url(r'^index/', views.index),    
url(r'^home/', views.Home.as_view()),

 

 

2.一、一對多:一類url對應一個函數或者一個類

如上循環字典的顯示,若是是主機信息,應該顯示主機名,點擊才顯示詳細信息。實現以下:

urls.py

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

 

 

注意:這裏網址實現的方式是相似http://127.0.0.1/detail-key1.html,而不是以前的detail?nid=key1的方式。這種方式,對於網站權重來講,搜索引擎更喜歡第一種方式。權重更好,會讓搜索引擎覺得網頁是靜態的。

views.py

USER_DICT = {
    'key1':{'name':'root1','eamil':'root@126.com'},
    'key2':{'name':'root2','eamil':'root@126.com'},
    'key3':{'name':'root3','eamil':'root@126.com'},
    'key4':{'name':'root4','eamil':'root@126.com'},
    'key5':{'name':'root5','eamil':'root@126.com'},
}
def index(request):
    return render(request, 'index.html', {'user_dict': USER_DICT})

def detail(request, nid):
    # nid: url里正則二次過濾獲取的值
    detail_info = USER_DICT[nid]
    return render (request, 'detail.html', {'detail_info': detail_info})

 

index.html

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

 

detail.html

<body>
    <h1>詳細信息</h1>
    <h6>用戶名:{{ detail_info.name }}</h6>
    <h6>郵箱:{{ detail_info.email }}</h6>
</body>

 

 

2.二、一對多,用法總結

  • 上面的示例中,二次匹配一個值,多傳一個形參匹配:

urls.py:url(r'^detail-(key\d+).html/', views.detail),

views.py:def detail(request, nid):

訪問網址:127.0.0.1/detail-key1.html

  • 若是再多匹配一個值,則以下:

urls.py:url(r'^detail-(key\d+)-(\d+).html/', views.detail),

views.py:def detail(request, nid, uid):

訪問網址:127.0.0.1/detail-key1-9.html

可見:url中二次匹配的值,和形參必須一一對應,但若是位置改了,裏面的代碼也得跟着改

  • 支持正則表達式 分組

urls.py:url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html/', views.detail),

直接第一個匹配的傳遞給nid,第二個匹配的傳遞給uid,這樣和views裏的函數形參位置沒有關係了。

views.py:def detail(request, nid, uid):

訪問網址:127.0.0.1/detail-key1-9.html

  • 分組時,個數不肯定*args,**kwargs也能使用

url(r'^detail-(key\d+)-(\d+).html/', views.detail), ——> def detail(request, *args):

url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html/', views.detail), ——> def detail(request, **kwargs):

三、name參數

以下內容:提交表單中action="/home/"須要跟着url中網址的修改而修改。

home.html

<form action="/home/" method="POST">
    <input type="text" name="user" />
    <input type="submit" />
</form>

 

urls.py

url(r'^home/', views.home),

 

 

其餘web框架也是這麼實現的,要改兩處都須要跟着修改。這裏django給提供了一個便捷的用法,name參數。

  • name :django 簡便用法

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

urls.py

url(r'^home/', views.home, name="homeee"),

 

home.html

<form action="{% url 'homeee' %}" method="POST">
    <input type="text" name="user" />
    <input type="submit" />
</form>

 

這樣寫上以後,url變了,只修改urls.py那裏一處就能夠了。

  • name :匹配地址裏有分組的處理

第二種:

# urls.py
url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
# views.py
def index(request,nid,uid):
    ......

 

# html
{% url "i2" 1 2 %}           # 成功匹配都,都跳轉到: yug/1/2/
 

第三種:

# urls.py
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),  # # buy/1/9/

 

# html
{% url "i3" pid=1 nid=9 %}   # buy/1/9/

 

 

上面是經過模板語音生成url,下面是經過reverse模塊生成url,兩種方式,實現功能同樣。

 
 
url(r'^asdfasdfasdf/', views.index, name='ii'),
url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),

#
views.py 文件 def func(request, *args, **kwargs): from django.urls import reverse # 根據名字反轉生成一個url url1 = reverse('i1') # asdfasdfasdf/ url2 = reverse('i2', args=(1,2,)) # yug/1/2/ url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/

 

 

做用:用戶完成某些操做後,跳轉到指定頁面。


# 注:
request.path_info   # 當前的url
def index(request,nid):
    print(request.path_info)
    return render(request, 'index.html')

<form action="{{ request.path_info }}" method="POST">

 

 

四、url 路由分發機制

前面的urls對應關係都在urls.py內,若是多個app,都須要在這裏引入。若是app多了,任何一個app的修改都會修改這一個urls文件。

在django裏面,有一個url分發的機制。

urls.py

from django.conf.urls import include
urlpatterns = [
    url(r'^monitor/', include("app02.urls")),   
]

 

app02/urls.py

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

urlpatterns = [
    url(r'^login/', views.login),
]

 

訪問http://127.0.0.1/monitor/login,就訪問的app02的login頁面。

五、默認值

六、命名空間

後續文章補充


轉載請務必保留此出處:http://www.cnblogs.com/lgeng/articles/7363951.html

 

<!-- END   -->

 

 

 

 

 

 

 

《版權說明》:本文--http://blog.csdn.net/fgf00/article/details/53649820

相關文章
相關標籤/搜索