Django POST遇Null IntegrityError,如何兼顾分类名称显示与提交?
解决Django序列化器中分类名称显示与POST提交兼容问题
问题根源:StringRelatedField是只读字段,只负责将分类对象转为名称返回给前端,但不处理POST请求的输入,导致提交时interest_category_id字段为空,触发非空约束错误。下面提供两种可行的解决思路:
方法一:拆分读写字段(推荐,简单直观)
定义两个字段:一个用于读取时返回分类名称,另一个用于写入时接收分类ID。
from rest_framework import serializers from .models import Project, InterestCategory class ProjectsSerializer(serializers.ModelSerializer): # 只读字段,返回分类名称,source指定关联的模型字段 interest_category_name = serializers.StringRelatedField(source='interest_category') # 写入用字段,接收分类ID,queryset用于验证输入合法性 interest_category = serializers.PrimaryKeyRelatedField(queryset=InterestCategory.objects.all()) class Meta: model = Project # 把两个字段都加到返回列表里 fields = ['id', 'project_name', 'interest_category', 'interest_category_name', '其他字段']
使用说明:
- GET请求时,前端会拿到
interest_category_name字段(显示分类名称,比如"Django"),interest_category字段返回ID(可按需选择是否暴露给前端) - POST提交时,前端只需要传
interest_category的ID值,序列化器会自动关联对应的分类对象,避免非空约束错误
方法二:自定义序列化字段(单字段搞定读写)
如果不想额外增加字段,可以自定义一个同时支持读写的字段,读取时返回名称,写入时处理ID(或名称)查询。
from rest_framework import serializers from .models import Project, InterestCategory class InterestCategoryField(serializers.Field): def to_representation(self, value): # 序列化输出时返回分类名称 return value.name def to_internal_value(self, data): # 反序列化输入时,根据传入的ID查询分类对象 try: return InterestCategory.objects.get(id=data) except InterestCategory.DoesNotExist: raise serializers.ValidationError("指定的分类不存在") class ProjectsSerializer(serializers.ModelSerializer): interest_category = InterestCategoryField() class Meta: model = Project fields = ['id', 'project_name', 'interest_category', '其他字段']
使用说明:
- GET请求时,
interest_category直接返回分类名称 - POST提交时,前端传分类ID即可,字段会自动查询并关联对象;如果需要支持传名称,把
get(id=data)改成get(name=data)即可(注意要保证分类名称唯一)
内容的提问来源于stack exchange,提问作者ckcAdmin
相关产品推荐
相关产品推荐

