高級
到此爲止,關於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)在瀏覽器中查看區域信息的列表頁面,效果如下圖:
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/
選擇文件後點擊按鈕上傳圖片。
7)圖片上傳目錄如下圖:
這裏只是完成圖片上傳的代碼,如果需要保存數據到表中需要創建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}}
{%else%}
<a href="/page{{pindex}}/">{{pindex}}</a>
{%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/目錄下。
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全棧學習資料記錄轉載,侵告刪