在Django里面,看看如何通过form来实现一个动态地select下拉框的效果。
首先看看静态的select的效果
models.py
class city(models.Model): name=models.CharField(max_length=32) #确保admin里面显示的是名字而不是object def __str__(self): return self.name
admin.py
from django.contrib import admin from app01.models import city admin.site.register(city)
然后在admin里面随便添加几条数据
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})
效果如下
这个时候,如果我在后台对city这个表进行了修改,刷新我的页面,显示的效果是不会改变的!只有当我重启整个Django,对应的数据才会在前台进行改变。
这是为什么呢?很简单,看看我们在class FM里面的定义,city3是这个类的静态字段,换句话说,这个字段在编译这个类的时候就初始化了,而当我们刷新页面,实例化对象的时候,这个静态字段的值并不会因为实例的不同而改变。那么为了改变对应的字段,解决方案就很明显了,要么在实例化以后的对象重新赋值,要么在实例化的过程中复制。这里我选择在实例化的过程中赋值,只需要自己重写一下init构造函数就行了。
修改代码:
注意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=‘请选择城市‘, )
效果如下
时间: 2024-10-24 01:14:52