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()
现在你可以做部分更新了 您想调用表单是有效的,但是您的表单如何知道用户只想更改和验证哪些字段?您想调用表单是有效的,但是您的表单如何知道用户只想更改和验证哪些字段?