Form组件动态绑定数据
一、概述(以单选下拉框为例)
用Form组件生成下拉框时,通常下拉框内的数据从数据库中获取。当在数据库中更新或者添加数据时,发现在刷新浏览器页面时,下拉框内的数据无变化。需要重新启动django在实际中这是不合理的
# views.py class Test2Form(forms.Form): user = fields.ChoiceField(choices=models.UserInfo.objects.values_list('id','username')) def test2(request): obj = Test2Form() return render(request,'test2.html',{"obj":obj}) # 数据库 id username email 1 小白 1212@qq.com 2 小花 12@qq.com # html <span>姑娘:{{ obj.user }}</span>
二、分析
step1:django启动时,class类就会运行,下拉框中获取数据库中的数据
step2:添加或修改数据库中的数据,刷新浏览器页面。下拉框中的数据不随着更新
step3:因为在刷新页面时,class中的类属性并不会再重新生成,所以一直保留最开始的数据
三、解决方法一
推荐使用:在类中重写__init__()方法,在页面刷新实例会对象时,执行方法更新数据
class Test2Form(forms.Form): user = fields.ChoiceField() # 在类中定义__init__()函数 def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) # self.fields必须写在super()下面。因为super会将类属性全拷贝,self.filelds才能取到值 self.fields['user'].choices=models.UserInfo.objects.values_list('id','username') def test2(request): obj = Test2Form() return render(request,'test2.html',{"obj":obj})
四、解决方法二
使用django自带的ModelChoiceField字段生成下拉框。看起来似乎比方法一简单,但是不推荐使用。因为需要在models中写str方法。如果在另一个的下拉框中要显示别的字段就不好操作了,与models耦合度高
from django.forms.models import ModelChoiceField # 需要导入 class Test2Form(forms.Form): user = ModelChoiceField(queryset=models.UserInfo.objects.all(),to_field_name='username') ''' queryset, # 查询数据库中的数据 empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中option中value的值对应的字段 ''' 在浏览器页面下拉框中显示 '表名 object' ,所以还需要修改model.py文件 # models.py class UserInfo(models.Model): username=models.CharField(max_length=32) email=models.EmailField(max_length=32) def __str__(self): return self.username