Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django modelForm更新某些字段_Django_Django Forms_Django Views - Fatal编程技术网

Django modelForm更新某些字段

Django modelForm更新某些字段,django,django-forms,django-views,Django,Django Forms,Django Views,我有一个“农场”模型和相应的模型形式,如下所示: class FarmForm(ModelForm): class Meta: model = Farm fields = ['farm_name','address','farm_size', 'latitude', 'longitude'] 我可以通过我的客户端应用程序保存一个新的场对象(它要求我填写模型表单中提到的所有字段) 我希望有另一个视图,在该视图中,我可以更新现有场,用户可能可以仅插入/更新他

我有一个“农场”模型和相应的模型形式,如下所示:

class FarmForm(ModelForm):
    class Meta:
        model = Farm
        fields = ['farm_name','address','farm_size', 'latitude', 'longitude']
我可以通过我的客户端应用程序保存一个新的场对象(它要求我填写模型表单中提到的所有字段)

我希望有另一个视图,在该视图中,我可以更新现有场,用户可能可以仅插入/更新他/她想要更改的字段。我尝试了以下方法,只通过Postman传递了一个字段值,但它给了我Form_not_有效错误:

@api_view(['POST'])
def updateFarm(request, farmId):
   farm = Farm.objects.get(id=farmId)
   form = FarmForm(instance=farm, data=request.POST)
   if form.is_valid():
       farm = form.save()
       farm = Farm.objects.filter(id=farm.id)
       serializer = FarmSerializer(farm, many=True)
       return JSONResponse(serializer.data) 
       #return Response("Data saved")
   else:
       return Response("Form not valid, insert correct fields.")

我怎样才能构建我的视图,让用户只更新那些他认为相关的字段?我的url:
url(r'^farms/update/(?P\d\d)/$,views.updateFarm),

您可以为模型中的每个字段生成一个布尔隐藏表单字段,该字段在修改字段时设置。例如

名称
输入:

<input id="id_name" maxlength="100" name="name" type="text">
您可以使用一些js跟踪对字段
name
的更改(使用普通js或jquery非常容易),并相应地将指定的
name\uu
更新为true/false

为了自动执行此操作并能够重复使用,您可以将其抽象到基本表单类中,并使表单保持简单:

class BaseForm(forms.ModelForm):
    suffix = '__specified'

    def __init__(self, **kwargs):
        super(BaseForm, self).__init__(**kwargs)

        fields = list(self.fields)
        for f in fields:
            # Set the field default value from the instance
            self.fields[f].widget.attrs['default'] = getattr(self.instance, f)

            # JS tracking field changes
            js = """
            document.getElementById("id_%s").value =
            this.value != this.getAttribute("default");
            """ % (f + self.suffix)
            self.fields[f].widget.attrs['onchange'] = js

            self.fields[f + self.suffix] = forms.BooleanField(
                widget=forms.HiddenInput(),
                required=False
            )

    def clean(self):
        data = super(BaseForm, self).clean()

        flags = [f for f in self.fields if self.suffix in f]
        for x in flags:
            specified = data.get(x, False)

            if not specified:
                field = x[:-len(self.suffix)]

                # If not specified grab it's current value from the instance
                data[field] = getattr(self.instance, field)

                # If the form validation complains that it's missing
                # clear the error since we are not changing it's value
                if field in self.errors:
                    del self.errors[field]

        return data
因此,您修改的表单:

class FarmForm(BaseForm):
    class Meta:
        model = Farm
        fields = ['farm_name','address','farm_size', 'latitude', 'longitude']
注意,在GET函数中实例化表单时,您应该传递实例,或者直接从
UpdateView
继承视图,以便自动处理:

class MyView(UpdateView):
    template_name = 'my_template.html'
    form_class = FarmForm
    queryset = Farm.objects.all() 

现在你可以做部分更新了

您可以为模型中的每个字段生成一个布尔隐藏表单字段,该字段在修改字段时设置。例如
名称
输入:

<input id="id_name" maxlength="100" name="name" type="text">
您可以使用一些js跟踪对字段
name
的更改(使用普通js或jquery非常容易),并相应地将指定的
name\uu
更新为true/false

为了自动执行此操作并能够重复使用,您可以将其抽象到基本表单类中,并使表单保持简单:

class BaseForm(forms.ModelForm):
    suffix = '__specified'

    def __init__(self, **kwargs):
        super(BaseForm, self).__init__(**kwargs)

        fields = list(self.fields)
        for f in fields:
            # Set the field default value from the instance
            self.fields[f].widget.attrs['default'] = getattr(self.instance, f)

            # JS tracking field changes
            js = """
            document.getElementById("id_%s").value =
            this.value != this.getAttribute("default");
            """ % (f + self.suffix)
            self.fields[f].widget.attrs['onchange'] = js

            self.fields[f + self.suffix] = forms.BooleanField(
                widget=forms.HiddenInput(),
                required=False
            )

    def clean(self):
        data = super(BaseForm, self).clean()

        flags = [f for f in self.fields if self.suffix in f]
        for x in flags:
            specified = data.get(x, False)

            if not specified:
                field = x[:-len(self.suffix)]

                # If not specified grab it's current value from the instance
                data[field] = getattr(self.instance, field)

                # If the form validation complains that it's missing
                # clear the error since we are not changing it's value
                if field in self.errors:
                    del self.errors[field]

        return data
因此,您修改的表单:

class FarmForm(BaseForm):
    class Meta:
        model = Farm
        fields = ['farm_name','address','farm_size', 'latitude', 'longitude']
注意,在GET函数中实例化表单时,您应该传递实例,或者直接从
UpdateView
继承视图,以便自动处理:

class MyView(UpdateView):
    template_name = 'my_template.html'
    form_class = FarmForm
    queryset = Farm.objects.all() 

现在你可以做部分更新了

您想调用表单是有效的,但是您的表单如何知道用户只想更改和验证哪些字段?您想调用表单是有效的,但是您的表单如何知道用户只想更改和验证哪些字段?