Django REST Framework JSON API示例项目无法创建多态项目实例报错
我之前也碰到过一模一样的问题,结合官方示例和自己踩过的坑,给你梳理下靠谱的解决思路:
1. 先检查多态资源的类型映射配置
django-rest-framework-json-api必须明确知道每个多态子模型对应的资源类型名称,你得在项目的settings.py里做好配置。比如官方示例里有ArtProject和ResearchProject两个子模型,就需要加这段配置:
JSON_API = { 'POLYMORPHIC_RESOURCE_TYPES': { 'Project': { 'ArtProject': 'art-projects', 'ResearchProject': 'research-projects' } } }
这里要注意:资源类型名称(比如art-projects)必须和后续序列化器里的resource_type完全匹配,大小写、连字符都不能错,不然框架就会识别不出类型,抛出你看到的"Expected one of..."错误。
2. 确认序列化器的多态配置正确
父模型序列化器必须继承PolymorphicSerializer,并且准确指定子序列化器的映射关系:
from rest_framework_json_api.serializers import PolymorphicSerializer class ProjectSerializer(PolymorphicSerializer): model_class = Project serializers = { ArtProject: ArtProjectSerializer, ResearchProject: ResearchProjectSerializer }
同时每个子序列化器要明确设置resource_type,和settings里的映射对应上:
class ArtProjectSerializer(ModelSerializer): class Meta: model = ArtProject resource_type = 'art-projects' fields = '__all__'
3. 验证请求/响应的资源类型格式
当请求/projects时,框架会自动返回每个实例对应的资源类型;如果是POST创建资源,请求体里的type字段必须和配置一致,比如:
{ "data": { "type": "art-projects", "attributes": { "name": "我的艺术项目" } } }
要是请求里的type和框架预期的不匹配,直接就会触发类型错误。
4. 检查django-polymorphic的模型基础配置
确保父模型正确继承了PolymorphicModel,子模型正常继承父模型:
from polymorphic.models import PolymorphicModel class Project(PolymorphicModel): name = models.CharField(max_length=100) class ArtProject(Project): medium = models.CharField(max_length=50) class ResearchProject(Project): topic = models.CharField(max_length=100)
这是多态功能的基础,模型层配置错了,上层序列化肯定出问题。
5. 确认视图集的配置没问题
视图集要使用ModelViewSet这类兼容的视图类,并且指定父序列化器作为默认序列化器:
from rest_framework.viewsets import ModelViewSet class ProjectViewSet(ModelViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer
框架会自动根据实例的实际类型,选择对应的子序列化器处理,返回正确的资源类型。
我当时就是因为settings里的POLYMORPHIC_RESOURCE_TYPES映射写错了一个连字符,导致框架识别不出子模型对应的资源类型,改完就完全正常了,你可以按这个顺序排查试试。
内容的提问来源于stack exchange,提问作者lloydh

