Django不使用forms.py如何实现ChoiceField选择字段
无需创建forms.py实现ChoiceField下拉选择的方案
你不需要单独新建forms.py文件,直接在现有views.py里写逻辑就能实现分类下拉选择,两种常用实现方式如下:
方式1:重写视图的get_form方法修改字段
这种方式改动最小,不需要额外定义表单类,直接在原有CreateView基础上修改字段属性即可:
from django.forms import ChoiceField from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView from .models import Post, Category class PostCreateView(LoginRequiredMixin, CreateView): model = Post fields = ["category"] # 替换为你自己的提交成功跳转路径 success_url = "/post/list/" def get_form(self, form_class=None): form = super().get_form(form_class) # 从数据库动态拉取所有分类,组装成ChoiceField需要的(存储值, 显示值)元组格式 category_choices = [(cat.Name, cat.Name) for cat in Category.objects.all()] # 增加空选项提示 category_choices.insert(0, ("", "请选择文章分类")) # 替换原category字段为下拉选择字段 form.fields["category"] = ChoiceField( choices=category_choices, label="分类", initial="Unclassified" ) return form
方式2:直接在views.py内定义表单类
如果需要给字段加更多校验、样式控制,可以直接把表单类写在views.py里,不需要单独建文件:
from django import forms from django.forms import ChoiceField from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView from .models import Post, Category # 表单类直接写在views.py中即可 class PostForm(forms.ModelForm): class Meta: model = Post fields = ["category"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 动态加载分类选项 category_choices = [(cat.Name, cat.Name) for cat in Category.objects.all()] category_choices.insert(0, ("", "请选择文章分类")) self.fields["category"] = ChoiceField( choices=category_choices, label="分类", initial="Unclassified" ) class PostCreateView(LoginRequiredMixin, CreateView): model = Post form_class = PostForm success_url = "/post/list/"
注意事项
- 你当前
Category模型的字段用了大写开头的Name,不符合Python和Django的命名规范,建议改成小写name,避免后续出现引用错误,修改后对应代码里的cat.Name同步替换为cat.name即可 - 分类选项一定要在表单实例化时动态从数据库查询,不要写死固定选项,否则后续新增分类后下拉列表不会同步更新
- 如果后续表单逻辑越来越复杂,再考虑把表单类抽离到单独的
forms.py文件即可,当前需求下完全不需要新建文件。
内容的提问来源于stack exchange,提问作者Zak Meshou
相关产品推荐
相关产品推荐

