在Django裏面,看看如何經過form來實現一個動態地select下拉框的效果。html
首先看看靜態的select的效果python
models.pydjango
class city(models.Model): name=models.CharField(max_length=32) #確保admin裏面顯示的是名字而不是object def __str__(self): return self.name
admin.pyapp
from django.contrib import admin from app01.models import city admin.site.register(city)
而後在admin裏面隨便添加幾條數據ide
views.py函數
######################## Form ##################### from django import forms from django.forms import widgets from django.forms import fields from app01 import models from django.forms import ModelChoiceField class FM(forms.Form): #這裏使用value_list是由於傳遞給choices的格式恰好是一個列表包括的元組格式 city3=fields.ChoiceField( choices=models.city.objects.all().values_list('id', 'name'), widget=widgets.Select ) def fm(request): if request.method == "GET": obj=FM() return render(request,'fm.html',{'obj': obj})
效果以下orm
這個時候,若是我在後臺對city這個表進行了修改,刷新個人頁面,顯示的效果是不會改變的!只有當我重啓整個Django,對應的數據纔會在前臺進行改變。htm
這是爲何呢?很簡單,看看咱們在class FM裏面的定義,city3是這個類的靜態字段,換句話說,這個字段在編譯這個類的時候就初始化了,而當咱們刷新頁面,實例化對象的時候,這個靜態字段的值並不會由於實例的不一樣而改變。那麼爲了改變對應的字段,解決方案就很明顯了,要麼在實例化之後的對象從新賦值,要麼在實例化的過程當中複製。這裏我選擇在實例化的過程當中賦值,只須要本身重寫一下init構造函數就好了。對象
修改代碼:blog
注意super的使用,繼承父類的init方法,而後再執行本身的賦值語句
city3=fields.ChoiceField( #反正要從新賦值,靜態字段就沒有必要賦值了 choices=[] ) def __init__(self,*args,**kwargs): super(FM,self).__init__(*args,**kwargs) self.fields['city3'].choices=models.city.objects.all().values_list('id','name')
這樣就實現了動態地改變select內容的效果。
除此之外,Django自己也提供了一個內置的類來實現這個動態效果。
導入類,而後定義一個字段
from django.forms import ModelChoiceField city4=forms.ModelChoiceField( queryset=models.city.objects.all(), empty_label='請選擇城市', )
效果以下