You need to enable JavaScript to run this app. 如何在Django中保存ModelForm自定义字段的提交数据?
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中保存ModelForm自定义字段的提交数据?

问题原因及解决方案

核心问题点

  • 视图中读取POST参数的键名与表单定义的字段名不匹配:你表单中定义的时长字段名为duration,但代码中用request.POST.get('dur')取值,无法获取到对应数据
  • 直接从request.POST取值没有用到表单的校验能力,存在安全风险,推荐使用表单验证后生成的cleaned_data取值
  • 变量命名混淆:form.save(commit=False)返回的是Cities模型实例,继续赋值给form变量容易引发逻辑错误

修正后的视图代码

def add_city(request):
    data = dict()

    if request.method == 'POST':
        form = AddCityForm(request.POST)
        if form.is_valid():
            # 取出模型实例,不要覆盖form变量
            city_obj = form.save(commit=False)
            # 从cleaned_data取经过校验的字段值
            city_obj.city = form.cleaned_data['country']
            city_obj.duration = form.cleaned_data['duration']
            city_obj.something = form.cleaned_data['something']
            city_obj.save()
            messages.success(request, '城市添加成功')
            data['form_is_valid'] = True
        else:
            data['form_is_valid'] = False
    else:
        form = AddCityForm()
    context = {'form': form}
    data['html_form'] = render_to_string('cites/modal_1.html', context, request=request)
    return JsonResponse(data)

可选优化:Form层处理逻辑

如果你不想在视图里写赋值逻辑,也可以重写ModelForm的save方法,把字段赋值逻辑放到Form中,简化视图代码,修改forms.py:

class AddCityForm(forms.ModelForm):
    duration = forms.ChoiceField(widget=forms.RadioSelect(attrs={
        'style': 'background-color: #FAF9F9', 'class': 'mb-3, form-check-inline'}), choices=DURATION_CHOICES)
    country = forms.ChoiceField(widget=forms.RadioSelect(attrs={
        'style': 'background-color: #FAF9F9', 'class': 'mb-3, form-check-inline'}), choices=CITY_CHOICE)
    something = forms.CharField(widget=forms.TextInput(attrs={
        'style': 'background-color: #FAF9F9', 'class': 'mb-3'}))

    class Meta:
        model = Cities
        exclude = ['city', 'duration', 'something']
    
    def save(self, commit=True):
        instance = super().save(commit=False)
        instance.city = self.cleaned_data['country']
        instance.duration = self.cleaned_data['duration']
        instance.something = self.cleaned_data['something']
        if commit:
            instance.save()
        return instance

重写save方法后,视图中不需要再手动赋值,直接调用form.save()即可完成保存:

if form.is_valid():
    form.save()
    messages.success(request, '城市添加成功')
    data['form_is_valid'] = True

内容的提问来源于stack exchange,提问作者mar24n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 03:36:03