【问题标题】:django edit forms dont keep valuesdjango 编辑表单不保留值
【发布时间】:2019-04-17 18:41:42
【问题描述】:

我为add 和edit 表单创建了一个简单的Django 表单。 我的问题出在我使用 ModelChoiceField 的人员领域。

在编辑表单中,除了字段ModelChoiceField 之外,所有值都解析正确。 在编辑表单中,该字段为空且不保留值,知道为什么吗??

def edit_work(request, pk):
    instance = get_object_or_404(work, id=pk)
    form = workForm(request.POST or None,instance=instance)
    if form.is_valid():
        note = form.save(commit=False)
        note.save()
        return HttpResponseRedirect('/work/success/')
    return render(request,'edit_work.html', {'form': form})


 def add_work(request):
     if request.method == "POST":
         form = workForm(request.POST)
         if form.is_valid():
             note = form.save(commit=False)
             note.save()
             return render(request, "succes/erga_success.html")
     else:
         form = workForm()
     return render(request, 'add_work.html',{'form':form})

forms.py

class workForm(forms.ModelForm):
    peaople=forms.ModelChoiceField(queryset=User.objects.all(),required=False, error_messages={
            'invalid': _("---")})
    class Meta:
        model = work
        fields = (__all__")

html页面:

     <form  enctype="multipart/form-data" method="POST" action="">{% csrf_token %}
     {{form.peaople}}
     .........
     <input type="submit" value="create">
     </form>

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    该值没有被保留,因为您没有将它保存在任何地方,也没有分配它。

    1. 将值保存在某处。
    # views.py
    
    # in both view functions
    if form.is_valid():
        note = form.save(commit=False)
        note.save()
        somemodel.people = form.cleaned_data.get("people")
        somemodel.save()
    
    1. 用保存的值初始化表单
    def edit_work(request, pk):
        instance = get_object_or_404(work, id=pk)
        form = workForm(request.POST or None,instance=instance, initial={'people': somemodel.people})
        if form.is_valid():
            note = form.save(commit=False)
            note.save()
            somemodel.people = form.cleaned_data.get("people")
            somemodel.save()
            return HttpResponseRedirect('/work/success/')
        return render(request,'edit_work.html', {'form': form})
    

    【讨论】:

    • 我的值保存工作正常我可以在详细模板和数据库中看到
    • 您是否尝试使用保存的值初始化表单?
    • 帮我可以看到保存的值
    • 那到底是什么问题?
    • 查看添加表单中的保存工作正常,但如果我尝试使用编辑表单,那么只有该字段为空,如果我使用 ModelChoiceField,请不要解析编辑表单中的值。
    【解决方案2】:

    为什么要手动指定peaople 字段?也许这些数据没有保存在 WorkModel.peaople 字段下,而是手动保存在其他地方?考虑到 ModelChoiceField 是单个值,那么该字段很可能是 ForeignKey 并且命名不同(不是peaople):如果 ModelForm 的自定义字段与模型上的同名字段不匹配,则默认不填充。

    可能的解决方案:

    • 如果模型字段名称与模型字段名称不同,则在初始化表单时应传递initial={'peaople': instance.some_human_fk_field} 参数。
    • 如果您只需要将一些现有模型字段(例如some_human_fk_field)的widget/label/error_message等更改为ModelChoiceField, 'people', {'invalid': _("---")},那么您完全可以don't need to define custom field:
    class workForm(forms.ModelForm): 
        class Meta:
            model = work
            fields = ("__all__")
            labels = {
                'some_human_fk_field': _('People'),
            }
            error_messages = {
                'some_human_fk_field': {
                    'invalid': _("---"),
                },
            }
            field_classes = {
                'some_human_fk_field': forms.ModelChoiceField,
            }
    
        def __init__(self, *args, **kwargs):
            super(workForm, self).__init__(*args, **kwargs)
    
            self.fields['some_human_fk_field'].queryset = User.objects.all()
            # Or you can dynamically determine queryset, for example you want to accout 'Work.owner.company' field: 
            # limiting_factor = None
            # if self.instance.pk:
            #     limiting_factor = self.instance.owner.company
            # elif self.data:
            #     _owner_pk = self.data.get('owner')
            #     limiting_factor = Company.objects.get(owners_set__pk=_owner_pk)
            # elif self.initial and self.initial.get('owner'):
            #     limiting_factor = self.initial['owner'].company
    
            # if limiting_factor:
            #     self.fields['some_human_fk_field'].queryset = build_qs_from_limiting_factor(
            #         User.objects.all(),
            #         company=limiting_factor
            #     )
            # else:
            #     self.fields['some_human_fk_field'].queryset = User.objects.all()
    
    
    • 如果 work 模型上的 peaople 字段不是 FK(例如 TextField),那么您需要在表单初始化后“手动设置”field.initial:
    class workForm(forms.ModelForm): 
        ...
        def __init__(self, *args, **kwargs):
            super(workForm, self).__init__(*args, **kwargs)
            if self.instance.pk and self.instance.peaople:
                self.fields['peaople'].initial = User.objects.filter(pk=self.instance.peaople)  # or `username=self.instance.peaople` depending on what you are really saving there
    
    

    【讨论】:

    • 我很抱歉,因为我之前没有提到它是我的错 People 字段是一个文本字段而不是 fk 。只是我想选择一些用户名,我尝试使用选择字段modelfield 但不要显示空选项来选择,因为那是一些选项字段
    • 如果它是一个文本字段,那么你应该在调用super().__init_(...)之后更改workForm.__init__中字段的initial参数:if self.instance and self.instance.peaople: self.fields['peaople'].initial = User.objects.filter(pk=int(self.instance.peaople)).first()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 2016-03-11
    • 2018-12-03
    • 1970-01-01
    • 2015-12-19
    • 2016-05-11
    • 1970-01-01
    相关资源
    最近更新 更多