仅使用字符串作为键修改Django模型字段时报错如何解决
问题原因
Django ORM返回的模型实例是普通Python对象,并未实现__setitem__魔法方法,因此不支持类似字典的实例[键名]赋值语法,所以运行时会抛出TypeError异常。
解决方法
使用Python内置的setattr()函数即可实现通过字符串类型的字段名修改模型实例属性,语法为setattr(实例对象, 属性名字符串, 要设置的值)。
基础实现代码
import json from typing import Any from django.http import HttpResponse from django.contrib.auth.models import User # ... 视图函数其他逻辑 changes: dict[str, Any] = json.loads(request.body) user: User = User.objects.get(id=user_id) for key, value in changes.items(): setattr(user, key, value) user.save() response = json.dumps([{ 'Success' : 'User changed successfully!'}]) return HttpResponse(response, content_type='application/json')
优化建议(推荐)
直接遍历前端传入的字段进行修改存在安全风险,可能出现用户传入不存在的字段、篡改敏感字段(比如is_superuser、is_staff权限字段)的问题,建议增加字段白名单校验,同时指定update_fields提升保存性能:
changes: dict[str, Any] = json.loads(request.body) # 按需修改允许用户更新的字段列表 ALLOWED_FIELDS = {"username", "email", "first_name", "last_name"} user: User = User.objects.get(id=user_id) updated_fields = [] for key, value in changes.items(): if key in ALLOWED_FIELDS: setattr(user, key, value) updated_fields.append(key) # 仅保存修改过的字段,减少数据库操作开销 user.save(update_fields=updated_fields)
如果你的项目已经引入了Django REST Framework,也可以直接使用序列化器完成参数校验、字段赋值的逻辑,代码可维护性更高。
内容的提问来源于stack exchange,提问作者lionel
相关产品推荐
相关产品推荐

