python - 由于 IntegrityError 类型的 TypeError 对象不是 JSON 可序列化的,因此无法使用 DRF 将数据插入模型
问题描述
我有一个表单数据,我想将其插入两个不同的模型中。所以起初我创建了两个模型,如下所示 -
这是模型User。
class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=255, blank=False)
last_name = models.CharField(max_length=255, blank=False)
email = models.EmailField(max_length=255, blank=False, unique= True)
phone_number = models.BigIntegerField(blank=False, unique= True)
password = models.TextField(blank=False)
company_name = models.CharField(max_length=255, blank=True)
is_active = models.BooleanField(default= True)
role = models.ForeignKey(Role, on_delete=models.CASCADE, blank=False)
business = models.ForeignKey(Businesses, on_delete=models.CASCADE, blank=True)
objects = UserManager()
USERNAME_FIELD = 'email'
def __str__(self):
return 'User Object ({})'.format(self.id)
这是模型DeliveryAgent。
class DeliveryAgentVehicle(models.Model):
vehicle_model = models.CharField(max_length=255, blank=False)
year_of_make = models.IntegerField(blank=False)
vehicle_photo = models.ImageField(upload_to='vehicle_photo/', max_length=None, null=True, blank=False)
driver_license = models.ImageField(upload_to='driver_license/', max_length=None, blank=False)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
def __str__(self):
return 'DeliveryAgentVehicle Object ({})'.format(self.id)
然后我创建了名为DeliveryAPIView()的APIView。
在这个视图中,我首先声明了 parser_classes。然后在 post 方法中,我通过添加 key 作为角色和id
(角色Delivery_agent
)作为值来更新 request.data 字典。我这样做是为了让这个视图只会创建类型的用户Delivery_Agent
class DeliveryAPIView(APIView):
parser_classes = (FormParser, MultiPartParser)
def post(self, request, format=None):
request.data['role'] = Role.objects.get(role_name='Delivery_agent').id
deserialized_data = DeliverySerializer(data=request.data)
if deserialized_data.is_valid():
try:
delivery_agent = deserialized_data.save()
except IntegrityError as identifier:
return Response(identifier)
return Response({
"message":"Done"
})
由于我想将表单数据存储到两个不同的模型中,因此我将validate_data
字典拆分为两个单独的字典delivey_agent_vehicle
和delivery_agent
序列化程序。
要将车辆详细信息与送货代理映射,我首先需要拥有user_id
送货代理。因此,要创建交付代理,我必须将字典传递delivey_agent
给create_user()
属于User
模型经理的方法。然后期望它将创建交付代理并返回交付代理的字符串表示实例,我调用create()
了方法DeliveryAgentVehicle
来插入交付代理的车辆详细信息。
这就是我的序列化程序的样子 -
class DeliverySerializer(serializers.Serializer):
email = serializers.EmailField(max_length=255, required=True)
password = serializers.CharField(max_length=255, required=True)
first_name = serializers.CharField(max_length=255, required=True)
last_name = serializers.CharField(max_length=255, required=True)
phone_number = serializers.IntegerField(required=True)
role = serializers.IntegerField(required=True)
vehicle_model = serializers.CharField(max_length=255, required=True)
year_of_make = serializers.CharField(max_length=255, required=True)
photo_of_vehicle = serializers.ImageField(max_length=None, allow_empty_file=False)
driver_license = serializers.ImageField(max_length=None, allow_empty_file=False)
def create(self, validated_data):
validated_data['role'] = Role.objects.get(pk=validated_data['role'])
delivey_agent={}
delivey_agent['email'] = validated_data['email']
delivey_agent['password'] = validated_data['password']
delivey_agent['first_name'] = validated_data['first_name']
delivey_agent['last_name'] = validated_data['last_name']
delivey_agent['phone_number'] = validated_data['phone_number']
delivey_agent['role'] = validated_data['role']
agent_id = User.objects.create_user(**delivey_agent)
delivey_agent_vehicle={}
delivey_agent_vehicle['vehicle_model'] = validated_data['vehicle_model']
delivey_agent_vehicle['vehicle_model'] = validated_data['year_of_make']
delivey_agent_vehicle['vehicle_model'] = validated_data[ 'photo_of_vehicle']
delivey_agent_vehicle['vehicle_model'] = validated_data['driver_license']
delivey_agent_vehicle['user'] = agent_id
agent_vehicle_id = DeliveryAgentVehicle.objects.create(**delivey_agent_vehicle)
print(delivey_agent_vehicle)
print(delivey_agent)
return agent_id
这是它返回的错误 -
Internal Server Error: /users/delivery/signup/
Traceback (most recent call last):
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/rest_framework/renderers.py", line 103, in render
allow_nan=not self.strict, separators=separators
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/rest_framework/utils/json.py", line 25, in dumps
return json.dumps(*args, **kwargs)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Users/jeetpatel/Desktop/env/lib/python3.7/site-packages/rest_framework/utils/encoders.py", line 67, in default
return super().default(obj)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type IntegrityError is not JSON serializable
解决方案
你的错误在这里:
try:
delivery_agent = deserialized_data.save()
except IntegrityError as identifier:
return Response(identifier)
响应期望一个 JSON 可序列化对象返回给用户,该对象通常是序列化器数据,一个字典。但是,您将IntegrityError
捕获的对象传递给它。
如果您想将原始数据库错误消息返回给客户端(这是不可取的),您应该执行以下操作:
try:
delivery_agent = deserialized_data.save()
except IntegrityError as identifier:
return Response({
"message":str(identifier)
}, status=400)
推荐阅读
- excel - 使用拆分 VBA 的类型不匹配
- python - Reformation of the unique list to another type of list in Python
- angular - Angular Material Official Getting Started 构建成功,但添加新模块失败
- azure - 如何执行 Azure 数据工厂管道 X 次(对于 X 个不同的参数值)?
- c - 在 printf - C 中连接字符串和 int
- php - 在laravel中下载视频特定部分的功能
- sql - concatenate multiple columns but avoid 2 cell if one cell is in blank or null in sql server
- bash - Bash - 如果根据前两列值发现重复项,则需要获取带有行号的记录
- mapbox - Mapbox 在移动浏览器中使用 unproject 的结果不准确
- unity3d - 如何更改 Unity 中的音频采样率?