Django 表单 (中)-动态实现select效果

在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

wKiom1nMjtWAQpbYAABBE-fXDQA300.png


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

wKiom1nMj6zjxA25AAAGvjoUy_s822.png


这个时候,若是我在后台对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='请选择城市',
)


效果以下


wKiom1nMkkiRD_jRAAAIzQIIvEo676.png

相关文章
相关标签/搜索