Django篇(5)高級

高級

到此爲止,關於Django框架的三大塊M、V、T已經全部講完了,接下來學習一些其它的知識點,這些知識點不在三大塊範圍內,Django提供了這些功能後,可以幫助我們更快更好的完成開發。

主要知識點如下:

  • 靜態文件處理
  • 中間件
  • 上傳圖片
  • Admin站點
  • 分頁
  • 示例:省市區選擇,jquery,ajax

1、創建示例項目

1)創建項目demo5。

django-admin startproject demo5

2)進入項目目錄demo5,創建應用app1。

cd demo5
python manage.py startapp app1

3)在demo5/settings.py中INSTALLED_APPS項安裝應用。

4)在demo5/settings.py中DATABASES項配置使用MySQL數據庫demo5。

5)在demo5/settings.py中TEMPLATES項配置模板查找路徑。

6)創建模板目錄結構如下:

7)打開demo5/urls.py文件,包含app1的url配置。

8)在app1/目錄下創建urls.py,配置url。

from django.conf.urls import url
from app1 import views
urlpatterns=[
    url(r'^$',views.index),
]

10)打開app1/views.py文件,定義視圖index。

from django.shortcuts import render

def index(request):
    return render(request,'app1/index.html')

11)在templates/app1目錄下創建文件index.html,代碼如下:

<html>
<head>
    <title>常用技術練習</title>
</head>
<body>
<h1>今天學習常用的技術</h1>
</body>
</html>

12)打開app1/models.py文件,定義模型類AeraInfo,結構參照第二部分設計。

from django.db import models

#定義地區模型類,存儲省、市、區縣信息
class AreaInfo(models.Model):
    atitle=models.CharField(max_length=30)#名稱
    aParent=models.ForeignKey('self',null=True,blank=True)#父級

1、靜態文件

項目中的CSS、圖片、js都是靜態文件。一般會將靜態文件放到一個單獨的目錄中,以方便管理。在html頁面中調用時,也需要指定靜態文件的路徑,Django中提供了一種解析的方式配置靜態文件路徑。靜態文件可以放在項目根目錄下,也可以放在應用的目錄下,由於有些靜態文件在項目中是通用的,所以推薦放在項目的根目錄下,方便管理。

示例

1)在demo5/settings.py文件中定義靜態文件存放的物理目錄。

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

2)在項目根目錄下創建static目錄,再創建img、css、js目錄。

3)在app1/views.py中定義視圖static_test。

def static_test(request):
    return render(request,'app1/static_test.html')

4)在app1/urls.py中配置url。

    url(r'^static_test/$',views.static_test),

5)在templates/app1/下創建static_test.html文件。

<html>
<head>
    <title>靜態文件</title>
</head>
<body>
<img src="/static/img/sta.png"/>
</body>
</html>

6)保存圖片到static/img/目錄下,名稱爲sta.png。

7)運行服務器,瀏覽效果如下圖:
在這裏插入圖片描述

配置靜態文件

Django提供了一種配置,可以在html頁面中可以隱藏真實路徑。

1)在demo5/settings.py文件中修改STATIC_URL項。

# STATIC_URL = '/static/'
STATIC_URL = '/abc/'

2)刷新瀏覽器,圖片找不到了,效果如下圖:
在這裏插入圖片描述

3)修改templates/app1/static_test.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>靜態文件</title>
</head>
<body>
<h1>下面沒有修改的圖片</h1>
<img src="static/img/sta.jpg" alt="">
<hr>
<h1>下面是修改路徑後的圖片</h1>
<img src="aaa/img/sta.jpg" alt="">
</body>
</html>

3)刷新瀏覽器,效果如下圖:

在這裏插入圖片描述

4)查看網頁源代碼,發現可以網址和真實地址之間沒有關係。

在這裏插入圖片描述

爲了安全可以通過配置項隱藏真實圖片路徑,在模板中寫成固定路徑,後期維護太麻煩,可以使用static標籤,根據配置項生成靜態文件路徑。

1)修改templates/app1/static_test.html如下:

<html>
<head>
    <title>靜態文件</title>
</head>
<body>
修改前:<img src="/static/img/sg.png"/>
<hr>
修改後:<img src="/abc/img/sg.png"/>
<hr>
動態配置:
{%load static from staticfiles%}
<img src="{%static "img/sg.png" %}"/>
</body>
</html>

2)刷新瀏覽器

查看網頁源代碼如下圖:

在這裏插入圖片描述

說明:這種方案可以隱藏真實的靜態文件路徑,但是結合Nginx佈署時,會將所有的靜態文件都交給Nginx處理,而不用轉到Django部分,所以這項配置就無效了。

2、中間件

Django中的中間件是一個輕量級、底層的插件系統,可以介入Django的請求和響應處理過程,修改Django的輸入或輸出。中間件的設計爲開發者提供了一種無侵入式的開發方式,增強了Django框架的健壯性,其它的MVC框架也有這個功能,名稱爲IoC。

Django在中間件中預置了五個方法,這五個方法的區別在於不同的階段執行,對輸入或輸出進行干預,方法如下:

1)初始化:無需任何參數,服務器響應第一個請求的時候調用一次,用於確定是否啓用當前中間件。

def __init__(self):
    pass

2)處理請求前:在每個請求上,request對象產生之後,url匹配之前調用,返回None或HttpResponse對象。

def process_request(self, request):
    pass

3)處理視圖前:在每個請求上,url匹配之後,視圖函數調用之前調用,返回None或HttpResponse對象。

def process_view(self, request, view_func, *view_args, **view_kwargs):
    pass

4)處理響應後:視圖函數調用之後,所有響應返回瀏覽器之前被調用,在每個請求上調用,返回HttpResponse對象。

def process_response(self, request, response):
    pass

5)異常處理:當視圖拋出異常時調用,在每個請求上調用,返回一個HttpResponse對象。

def process_exception(self, request,exception):
    pass

示例

中間件是一個獨立的python類,,可以定義這五個方法中的一個或多個。

1)在app1/目錄下創建middleware.py文件,代碼如下:

class my_mid(object):
    def __init__(self):
        print ('--------------init')

    def process_request(self,request):
        print ('--------------request')

    def process_view(self,request, view_func, *view_args, **view_kwargs):
        print ('--------------view')

    def process_response(self,request, response):
        print ('--------------response')
        return response

2)在demo5/settings.py文件中,向MIDDLEWARE_CLASSES項中註冊。

在這裏插入圖片描述

3)修改app1/views.py中視圖index。

def index(request):
    print ('======index======')
    return render(request,'app1/index.html')

4)運行服務器,命令行中效果如下圖:
在這裏插入圖片描述

3)刷新頁面,命令行中效果如下圖:

在這裏插入圖片描述

異常中間件

1)在app1/middleware.py中定義兩個異常類如下:

class exp1:
    def process_exception(self,request,exception):
        print '--------------exp1'
class exp2:
    def process_exception(self,request,exception):
        print '--------------exp2'

2)在demo5/settings.py文件中,向MIDDLEWARE_CLASSES項中註冊。
在這裏插入圖片描述

3)修改app1/views.py中視圖index。

def index(request):
    print ('======index======')
    raise Exception('自定義異常')
    return render(request,'app1/index.html')

總結:如果多個註冊的中間件類中都有process_exception的方法,則先註冊的後執行。

3、Admin站點

內容發佈的部分由網站的管理員負責查看、添加、修改、刪除數據,開發這些重複的功能是一件單調乏味、缺乏創造力的工作,爲此,Django能夠根據定義的模型類自動地生成管理模塊。

在第一部分對管理站點做了簡單介紹,現在做詳細講解。在Django項目中默認啓用Admin管理站點。

1)準備工作:創建管理員的用戶名和密碼。

python manage.py createsuperuser

按提示填寫用戶名、郵箱、密碼。

2)使用:在應用的admin.py中註冊模型類

例:打開app1/admin.py文件,註冊地區模型。

from django.contrib import admin
from app1.models import *

admin.site.register(AreaInfo)

3)輸入如下網址:

http://127.0.0.1:8000/admin/

按提示填寫用戶名、密碼,點擊“Log in”按鈕登錄。

登錄成功後,可以看到AreaInfos,可以進行增加、修改、刪除、查詢的管理。

3.1、控制管理頁展示

類ModelAdmin可以控制模型在Admin界面中的展示方式,主要包括在列表頁的展示方式、添加修改頁的展示方式。

1)在app1/admin.py中,註冊模型類前定義管理類AreaAdmin。

class AreaAdmin(admin.ModelAdmin):
    pass

管理類有兩種使用方式:

  • 註冊參數
  • 裝飾器

註冊參數:打開app1/admin.py文件,註冊模型類代碼如下:

admin.site.register(AreaInfo,AreaAdmin)

裝飾器:打開app1/admin.py文件,在管理類上註冊模型類,代碼如下:

@admin.register(AreaInfo)
class AreaAdmin(admin.ModelAdmin):
    pass

接下來介紹如何控制列表頁、增加修改頁展示效果。

3.2、列表頁選項

頁大小

每頁中顯示多少條數據,默認爲每頁顯示100條數據,屬性如下:

list_per_page=100

1)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    list_per_page = 10

2)在瀏覽器中查看區域信息的列表頁面,效果如下圖:
[外鏈圖片轉存失敗(img-5Z2wwtSB-1562758888375)(images/p5_1_1.png)]

3.21、"操作選項"的位置

頂部顯示的屬性,設置爲True在頂部顯示,設置爲False不在頂部顯示,默認爲True。

actions_on_top=True

底部顯示的屬性,設置爲True在底部顯示,設置爲False不在底部顯示,默認爲False。

actions_on_bottom=False

1)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    actions_on_top = True
    actions_on_bottom = True

2)在瀏覽器中刷新效果如下圖:

在這裏插入圖片描述

3.2.2、列表中的列

屬性如下:

list_display=[模型字段1,模型字段2,...]

1)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    list_display = ['id','atitle']

2)在瀏覽器中刷新效果如下圖:
在這裏插入圖片描述

點擊列頭可以進行升序或降序排列。

3.2.3、將方法作爲列

列可以是模型字段,還可以是模型方法,要求方法有返回值。

1)打開app1/models.py文件,修改AreaInfo類如下:

class AreaInfo(models.Model):
    ...
    def title(self):
        return self.atitle

2)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    list_display = ['id','atitle','title']

3)在瀏覽器中刷新效果如下圖:

在這裏插入圖片描述

方法列是不能排序的,如果需要排序需要爲方法指定排序依據。

admin_order_field=模型類字段

1)打開app1/models.py文件,修改AreaInfo類如下:

class AreaInfo(models.Model):
    ...
    def title(self):
        return self.atitle
    title.admin_order_field='atitle'

2)在瀏覽器中刷新效果如下圖:

在這裏插入圖片描述

列標題

列標題默認爲屬性或方法的名稱,可以通過屬性設置。需要先將模型字段封裝成方法,再對方法使用這個屬性,模型字段不能直接使用這個屬性。

short_description='列標題'

1)打開app1/models.py文件,修改AreaInfo類如下:

class AreaInfo(models.Model):
    ...
    title.short_description='區域名稱'

2)在瀏覽器中刷新效果如下圖:
在這裏插入圖片描述

關聯對象

無法直接訪問關聯對象的屬性或方法,可以在模型類中封裝方法,訪問關聯對象的成員。

1)打開app1/models.py文件,修改AreaInfo類如下:

class AreaInfo(models.Model):
    ...
    def parent(self):
        if self.aParent is None:
          return ''
        return self.aParent.atitle
    parent.short_description='父級區域名稱'

2)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    list_display = ['id','atitle','title','parent']

3)在瀏覽器中刷新效果如下圖:

在這裏插入圖片描述

3.2.4、右側欄過濾器

屬性如下,只能接收字段,會將對應字段的值列出來,用於快速過濾。一般用於有重複值的字段。

list_filter=[]

1)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    list_filter=['atitle']

2)在瀏覽器中刷新效果如下圖:
在這裏插入圖片描述

3.2.5、搜索框

屬性如下,用於對指定字段的值進行搜索,支持模糊查詢。列表類型,表示在這些字段上進行搜索。

search_fields=[]

1)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    search_fields=['atitle']

2)在瀏覽器中刷新效果如下圖:
在這裏插入圖片描述

3.2.6、中文標題

1)打開app1/models.py文件,修改模型類,爲屬性指定verbose_name參數,

class AreaInfo(models.Model):
    atitle=models.CharField(verbose_name='標題',max_length=30)#名稱
    ...

2)在瀏覽器中刷新效果如下圖:
在這裏插入圖片描述

3.3、編輯頁選項

3.3.1、顯示字段順序

屬性如下:

fields=[]

1)點擊某行ID的鏈接,可以轉到修改頁面,默認效果如下圖:
在這裏插入圖片描述

2)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    fields=['aParent','atitle']

3)刷新瀏覽器效果如下圖:
在這裏插入圖片描述

在下拉列表中輸出的是對象的名稱,可以在模型類中定義str方法用於對象轉換字符串。

1)打開app1/models.py文件,修改AreaInfo類,添加str方法。

class AreaInfo(models.Model):
    ...
    def __str__(self):
        return self.atitle

2)刷新瀏覽器效果如下圖:
在這裏插入圖片描述

3.3.2、分組顯示

屬性如下:

fieldset=(
    ('組1標題',{'fields':('字段1','字段2')}),
    ('組2標題',{'fields':('字段3','字段4')}),
)

1)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    # fields=['aParent','atitle']
    fieldsets = (
        ('基本', {'fields': ['atitle']}),
        ('高級', {'fields': ['aParent']})
    )

2)刷新瀏覽器效果如下圖:
在這裏插入圖片描述

說明:fields與fieldsets兩者選一使用。

3.3.3關聯對象

在一對多的關係中,可以在一端的編輯頁面中編輯多端的對象,嵌入多端對象的方式包括表格、塊兩種。 類型InlineModelAdmin:表示在模型的編輯頁面嵌入關聯模型的編輯。子類TabularInline:以表格的形式嵌入。子類StackedInline:以塊的形式嵌入。

1)打開app1/admin.py文件,創建AreaStackedInline類。

class AreaStackedInline(admin.StackedInline):
    model = AreaInfo#關聯子對象
    extra = 2#額外編輯2個子對象

2)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    inlines = [AreaStackedInline]

3)刷新瀏覽器效果如下圖:
在這裏插入圖片描述

可以用表格的形式嵌入。

1)打開app1/admin.py文件,創建AreaTabularInline類。

class AreaTabularInline(admin.TabularInline):
    model = AreaInfo#關聯子對象
    extra = 2#額外編輯2個子對象

2)打開app1/admin.py文件,修改AreaAdmin類如下:

class AreaAdmin(admin.ModelAdmin):
    ...
    inlines = [AreaTabularInline]

3)刷新瀏覽器效果如下圖:
在這裏插入圖片描述

3.4、重寫模板

1)在templates/目錄下創建admin目錄,結構如下圖:
在這裏插入圖片描述

2)打開當前虛擬環境中Django的目錄,再向下找到admin的模板,目錄如下:

/home/python/.virtualenvs/py_django/lib/python3.5/site-packages/django/contrib/admin/templates/admin

3)將需要更改文件拷貝到第一步建好的目錄裏,此處以base_site.html爲例。
在這裏插入圖片描述

編輯base_site.html文件:

{% extends "admin/base.html" %}

{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
<hr>
<h1>自定義的管理頁模板</h1>
<hr>
{% endblock %}

{% block nav-global %}{% endblock %}

4)在瀏覽器中轉到列表頁面,刷新後如下圖:
在這裏插入圖片描述

其它後臺的模板可以按照相同的方式進行修改。

4、上傳圖片

在python中進行圖片操作,需要安裝包PIL。

pip install Pillow==3.4.1

在Django中上傳圖片包括兩種方式:

  • 在管理頁面admin中上傳圖片
  • 自定義form表單中上傳圖片

上傳圖片後,將圖片存儲在服務器上,然後將圖片的路徑存儲在表中。

4.1、創建包含圖片的模型類

將模型類的屬性定義成models.ImageField類型。

1)打開app1/models.py文件,定義模型類PicTest。

class PicTest(models.Model):
    pic = models.ImageField(upload_to='app1/',verbose_name='圖片路徑')

2)回到命令行中,生成遷移。

python manage.py makemigrations

3)打開app1/migrations/0001_initial.py文件,刪除AreaInfo部分,因爲這個表已經存在。
在這裏插入圖片描述

4)回到命令行中,執行遷移。

python manage.py migrate

5)因爲當前沒有定義圖書、英雄模型類,會提示“是否刪除”,輸入“no”後回車,表示不刪除。
在這裏插入圖片描述

6)打開demo5/settings.py文件,設置圖片保存路徑。

因爲圖片也屬於靜態文件,所以保存到static目錄下。

MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")

7)在static目錄下創建media目錄,再創建應用名稱的目錄,此例爲app1。
在這裏插入圖片描述

4.2、在管理頁面admin中上傳圖片

1)打開app1/admin.py文件,註冊PicTest。

from django.contrib import admin
from app1.models import *

admin.site.register(PicTest)

2)運行服務器,輸入如下網址。

http://127.0.0.1:8000/admin/

在這裏插入圖片描述

3)點擊“Add”添加數據,打開新頁面。
在這裏插入圖片描述

4)選擇圖片,點擊“save”按鈕完成圖片上傳。 5)回到數據庫命令行,查詢表pictest中的數據如下圖:
在這裏插入圖片描述

6)圖片被保存到目錄static/media/app1/下,如下圖:
在這裏插入圖片描述

4.3、自定義form表單中上傳圖片

1)打開app1/views.py文件,創建視圖pic_upload。

def pic_upload(request):
    return render(request,'app1/pic_upload.html')

2)打開app1/urls.py文件,配置url。

    url(r'^pic_upload/$', views.pic_upload),

3)在templates/app1/目錄下創建模板pic_upload.html。

在模板中定義上傳表單,要求如下:

  • form的屬性enctype=“multipart/form-data”
  • form的method爲post
  • input的類型爲file
<html>
<head>
    <title>自定義上傳圖片</title>
</head>
<body>
    <form method="post" action="/pic_handle/" enctype="multipart/form-data">
        {%csrf_token%}
        <input type="file" name="pic"/><br>
        <input type="submit" value="上傳">
    </form>
</body>
</html>

4)打開app1/views.py文件,創建視圖pic_handle,用於接收表單保存圖片。

request對象的FILES屬性用於接收請求的文件,包括圖片。

from django.conf import settings
from django.http import HttpResponse
...
def pic_handle(request):
    f1=request.FILES.get('pic')
    fname='%s/app1/%s'%(settings.MEDIA_ROOT,f1.name)
    with open(fname,'wb') as pic:
        for c in f1.chunks():
            pic.write(c)
    return HttpResponse('OK')

5)打開app1/urls.py文件,配置url。

    url(r'^pic_handle/$', views.pic_handle),

6)運行服務器,在瀏覽器中輸入如下網址:

http://127.0.0.1:8000/pic_upload/

[外鏈圖片轉存失敗(img-NC7yEILD-1562758888403)(images/p4_2_1.png)]

選擇文件後點擊按鈕上傳圖片。

7)圖片上傳目錄如下圖:
[外鏈圖片轉存失敗(img-9a9NEZFZ-1562758888404)(images/p4_2_2.png)]

這裏只是完成圖片上傳的代碼,如果需要保存數據到表中需要創建PicTest對象完成保存。

4.4、顯示圖片

1)打開app1/views.py文件,創建視圖pic_show。

from app1.models import PicTest
...
def pic_show(request):
    pic=PicTest.objects.get(pk=1)
    context={'pic':pic}
    return render(request,'app1/pic_show.html',context)

2)打開app1/urls.py文件,配置url。

    url(r'^pic_show/$', views.pic_show),

3)在templates/app1/目錄下創建模板pic_show.html。

<html>
<head>
    <title>顯示上傳的圖片</title>
</head>
<body>
<img src="/static/media/{{pic.pic}}"/>
</body>
</html>

4)運行服務器,在瀏覽器中輸入如下網址:

http://127.0.0.1:8000/pic_show/

在這裏插入圖片描述

5、分頁

Django提供了數據分頁的類,這些類被定義在django/core/paginator.py中。 類Paginator用於對列進行一頁n條數據的分頁運算。類Page用於表示第m頁的數據。

5.1、Paginator類實例對象

  • 方法_init_(列表,int):返回分頁對象,第一個參數爲列表數據,第二個參數爲每頁數據的條數。
  • 屬性count:返回對象總數。
  • 屬性num_pages:返回頁面總數。
  • 屬性page_range:返回頁碼列表,從1開始,例如[1, 2, 3, 4]。
  • 方法page(m):返回Page類實例對象,表示第m頁的數據,下標以1開始。

5.2、Page類實例對象

  • 調用Paginator對象的page()方法返回Page對象,不需要手動構造。
  • 屬性object_list:返回當前頁對象的列表。
  • 屬性number:返回當前是第幾頁,從1開始。
  • 屬性paginator:當前頁對應的Paginator對象。
  • 方法has_next():如果有下一頁返回True。
  • 方法has_previous():如果有上一頁返回True。
  • 方法len():返回當前頁面對象的個數。
  • page.next_page_number,下一頁頁碼
  • page.previous_page_number,上一頁頁碼

示例

1)在app1/views.py文件中創建視圖page_test。

from django.core.paginator import Paginator
from app1.models import AreaInfo
...
#參數pIndex表示:當前要顯示的頁碼
def page_test(request,pIndex):
    #查詢所有的地區信息
    list1 = AreaInfo.objects.filter(aParent__isnull=True)
    #將地區信息按一頁10條進行分頁
    p = Paginator(list1, 10)
    #如果當前沒有傳遞頁碼信息,則認爲是第一頁,這樣寫是爲了請求第一頁時可以不寫頁碼
    if pIndex == '':
        pIndex = '1'
    #通過url匹配的參數都是字符串類型,轉換成int類型
    pIndex = int(pIndex)
    #獲取第pIndex頁的數據
    list2 = p.page(pIndex)
    #獲取所有的頁碼信息
    plist = p.page_range
    #將當前頁碼、當前頁的數據、頁碼信息傳遞到模板中
    return render(request, 'app1/page_test.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})

2)在app1/urls.py文件中配置url。

    url(r'^page(?P<pIndex>[0-9]*)/$', views.page_test),

3)在templates/app1/目錄下創建page_test.html模板文件。

<html>
<head>
    <title>分頁</title>
</head>
<body>
顯示當前頁的地區信息:<br>
<ul>
{%for area in list%}
<li>{{area.id}}--{{area.atitle}}</li>
{%endfor%}
</ul>
<hr>
顯示頁碼信息:當前頁碼沒有鏈接,其它頁碼有鏈接<br>
{%for pindex in plist%}
    {%if pIndex == pindex%}
        {{pindex}}&nbsp;&nbsp;
    {%else%}
        <a href="/page{{pindex}}/">{{pindex}}</a>&nbsp;&nbsp;
    {%endif%}
{%endfor%}
</body>
</html>

4)運行服務器,在瀏覽器中輸入如下網址:

http://127.0.0.1:8000/page/

在這裏插入圖片描述

5)點擊頁碼數字,效果如下圖:
在這裏插入圖片描述

6、案列:省市區下拉選擇地址

本示例講解在Django中使用jquery的ajax進行數據交互。 jquery框架中提供了.ajax、get、.post方法,用於進行異步交互,由於Django中默認使用CSRF約束,推薦使用get。

示例:實現省市區的選擇。

最終實現效果如圖:
在這裏插入圖片描述
1)將jquery文件拷貝到static/js/目錄下。

[外鏈圖片轉存失敗(img-Th88Xh2z-1562758888408)(images/p7_2.png)]

2)打開app1/views.py文件,定義視圖area1,用於顯示下拉列表。

#提供顯示下拉列表的控件,供用戶操作
def area1(request):
    return render(request,'app1/area1.html')

3)打開app1/urls.py文件,配置url。

    url(r'^area1/$', views.area1),

4)在templates/app1/目錄下創建area1.html。

<html>
<head>
    <title>省市區列表</title>
    <script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script>
    <script type="text/javascript">
        $(function(){
            //頁面加載完成後獲取省信息,並添加到省select
            $.get('/area2/',function(dic) {
                pro=$('#pro')
                $.each(dic.data,function(index,item){
                    pro.append('<option value='+item[0]+'>'+item[1]+'</option>');
                })
            });
            //爲省select綁定change事件,獲取市信息,並添加到市select
            $('#pro').change(function(){
                $.get('/area3_'+$(this).val()+'/',function(dic){
                    city=$('#city');
                    city.empty().append('<option value="">請選擇市</option>');
                    dis=$('#dis');
                    dis.empty().append('<option value="">請選擇區縣</option>');
                    $.each(dic.data,function(index,item){
                        city.append('<option value='+item[0]+'>'+item[1]+'</option>');
                    })
                });
            });
            //爲市select綁定change事件,獲取區縣信息,並添加到區縣select
            $('#city').change(function(){
                $.get('/area3_'+$(this).val()+'/',function(dic){
                    dis=$('#dis');
                    dis.empty().append('<option value="">請選擇區縣</option>');
                    $.each(dic.data,function(index,item){
                        dis.append('<option value='+item[0]+'>'+item[1]+'</option>');
                    })
                })
            });

        });
    </script>
</head>
<body>
<select id="pro">
    <option value="">請選擇省</option>
</select>
<select id="city">
    <option value="">請選擇市</option>
</select>
<select id="dis">
    <option value="">請選擇區縣</option>
</select>
</body>
</html>

5)運行服務器,在瀏覽器中輸入如下網址:

http://127.0.0.1:8000/area1/

瀏覽效果如下圖:
在這裏插入圖片描述

6)打開app1/views.py文件,定義視圖area2,用於獲取省信息。

from django.http import JsonResponse
...
#獲取省信息
def area2(request):
    list = AreaInfo.objects.filter(aParent__isnull=True)
    list2 = []
    for item in list:
        list2.append([item.id, item.atitle])
    return JsonResponse({'data': list2})

7)打開app1/urls.py文件,配置url。

    url(r'^area2/$', views.area2),

8)在瀏覽器中輸入如下網址。

http://127.0.0.1:8000/area2/

瀏覽效果如下圖:
在這裏插入圖片描述

9)打開app1/views.py文件,定義視圖area3,用於根據編號獲取對應的子級信息,如果傳遞的是省編號則獲取市信息,如果傳遞的是市編號則獲取區縣信息。

#根據pid查詢子級區域信息
def area3(request, pid):
    list = AreaInfo.objects.filter(aParent_id=pid)
    list2 = []
    for item in list:
        list2.append([item.id, item.atitle])
    return JsonResponse({'data': list2})

10)打開app1/urls.py文件,配置url。

    url(r'^area3_(\d+)/$', views.area3),

11)在瀏覽器中輸入如下網址:

http://127.0.0.1:8000/area3_140000/

瀏覽效果如下圖:
在這裏插入圖片描述

12)在瀏覽器中輸入如下網址:

http://127.0.0.1:8000/area1/

選擇效果如下圖:
在這裏插入圖片描述

最後:
文章爲18年python全棧學習資料記錄轉載,侵告刪

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章