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

2024-06-16 09:49:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前拥有以下代码:

HTTP/POST

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

Mike

表单.py

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

视图.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)

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


Tags: instancekeynamepyformjsontypestatus
1条回答
网友
1楼 · 发布于 2024-06-16 09:49:10

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视图的呈现表单中。这样,除非用户有意删除所有字段,否则所有字段都将与表单一起重新提交

相关问题 更多 >