在没有条件语句的情况下更新Django模型中的1个或多个字段

时间:2019-02-15 03:53:50

标签: python django

我目前有以下代码:

HTTP / POST

------WebKitFormBoundary2s9CNLxw7qrgzD94
Content-Disposition: form-data; name="first_name"

Mike

forms.py

class TenantUpdateForm(ModelForm):
    class Meta:
        model = Tenant
        fields = ["first_name", "last_name", "email", "birthday", "stars", "company",
              "position", "client_type", "phone", "identification", "comments"]

views.py

@csrf_exempt
@jwt_authentication
@require_http_methods(["POST"])
def update_tenant(request, unique_key):

    instance = get_object_or_404(Tenant, unique_key=unique_key)
    form = TenantUpdateForm(request.POST, instance=instance)

    if form.is_valid():
        form.save()
        payload = {"status": True,
                "description": "Tenant fields updated."}

        return HttpResponse(json.dumps(payload, indent=2, cls=json_encoder),
                            content_type='application/json',
                            status=200)
    else:
        payload = {"status": False,
                "description": "Form is invalid.",
                "form": form.errors.as_json()}

        return HttpResponse(json.dumps(payload, indent=2, cls=json_encoder),
                            content_type='application/json',
                            status=404)

到目前为止,一切正常。但是,当我尝试仅更新一个字段时,它会更改该字段,但其他所有字段都变为空白。

1 个答案:

答案 0 :(得分:1)

django表单的默认行为是更新模型的所有字段。如果未填写,它们将以None''的形式返回并以这种方式更新模型。如果要更改该行为,则必须在save函数中添加一些其他代码。这是我会尝试的方法:


from django.db import models

class TenantUpdateForm(ModelForm):
    def _post_clean(self):
        # intentionally override parent post-clean
        # it will overwrite our instance
        pass

    def save(commit=True):
        if not self.instance:
            # delegate to super class for creates, 
            # we only want to affect updates.
            return super(TenantUpdateForm, self).save(commit)
        for key in self.data.keys():      
            try:
                self.instance._meta.get_field(key)              
                value = self.cleaned_data[key]
                setattr(self.instance, key, value)
            except KeyError:
                pass
        if commit:
            self.instance.save()
        return self.instance   

    class Meta:
        model = Tenant
        fields = ["first_name", "last_name", "email", "birthday", "stars", "company",
              "position", "client_type", "phone", "identification", "comments"] 

请注意,这种方法需要权衡取舍:用户无法使用此表单使字段为空;但是,该表单将通过更新实例的一个字段来按您希望的方式工作。使用此类表单的典型方法是将实例传递到用于在get三视图中呈现表单的表单,以便旧字段以用户提交给此post的呈现表单显示视图。这样,除非用户有意删除它们,否则所有字段都将重新提交表单。