在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='请选择城市', )
效果以下