我有一个' 农场'模型和相应的ModelForm如下:
class FarmForm(ModelForm):
class Meta:
model = Farm
fields = ['farm_name','address','farm_size', 'latitude', 'longitude']
我可以通过我的客户端应用程序保存新的 Farm 对象(它要求我填写我的ModelForm中提到的所有字段)。
我希望有另一个视图,我可以在其中更新现有的 Farm ,用户可以在其中插入/更新他/她想要更改的字段。我通过邮递员只传递一个字段值尝试了类似下面的内容,但它给了我Form_not_valid错误:
@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(r'^farms/update/(?P<farmId>\d\d)/$', views.updateFarm),
答案 0 :(得分:0)
您可以为模型中的每个字段生成一个布尔隐藏的表单字段,该字段在修改字段时设置。例如name
输入:
<input id="id_name" maxlength="100" name="name" type="text">
后面会跟一个name__specified
隐藏输入:
<input id="id_name__specified" name="name__specified" type="hidden">
您可以使用一些j跟踪字段name
的更改(使用普通js或jquery非常容易),并相应地将name__specified
更新为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()
现在你可以进行部分更新了!