Django Rest Framework POST响应如何返回主键key与url字段
问题原因及解决方案
你遇到的POST请求返回key和url字段为空的问题,核心原因和解决方法如下:
核心原因
url字段基于HyperlinkedIdentityField生成,需要明确匹配路由规则,默认配置下如果你的模型主键不是id,或者路由名称不匹配,就会生成空值。key是数据库自动生成的主键,序列化时如果直接使用写入前的临时实例,还没有拿到数据库生成的主键值,就会返回空。
具体修改步骤
1. 修改序列化器配置
显式指定url字段的路由名称和查找字段,同时把key放入只读字段列表,无需单独声明:
# serializers.py class EventSerializer(serializers.HyperlinkedModelSerializer): host = serializers.StringRelatedField(read_only=True) # 显式定义url字段: # view_name对应urls.py中事件详情路由的名称,默认是event-detail,如果你注册路由时指定了自定义basename,改为「{你的basename}-detail」即可 # lookup_field指定用key字段作为路由参数匹配 url = serializers.HyperlinkedIdentityField( view_name="event-detail", lookup_field="key" ) class Meta: model = Event fields = ['url', 'key', 'start_date', 'end_date', 'subject', 'description', 'host'] read_only_fields = ['key']
2. 修改视图集配置
显式指定视图集的查找字段为key,可选重写create方法确保返回数据库写入后的最新实例:
# views.py from rest_framework import status from rest_framework.response import Response class EventViewSet(viewsets.ModelViewSet): queryset = Event.objects.all() serializer_class = EventSerializer # 指定用key字段查找单条数据,和序列化器的lookup_field对应 lookup_field = 'key' @action(detail=True) def skills(self, request, *args, **kwargs): return get_key_values(TblClsOne=EventSkills, TblClsTwo=Skills, table_one_column_name="event_id", table_one_fk_name='skill_id', table_two_column_name="skill_id", table_one_filter_value=kwargs["pk"]) def perform_create(self, serializer): serializer.save(host=self.request.user) # 可选:如果修改序列化器后key仍为空,添加这个方法强制读取写入后的实例 def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) # 重新从数据库拉取最新实例,确保自动生成的字段全部加载 new_instance = Event.objects.get(pk=serializer.instance.pk) res_serializer = self.get_serializer(new_instance) headers = self.get_success_headers(res_serializer.data) return Response(res_serializer.data, status=status.HTTP_201_CREATED, headers=headers)
修改完成后POST请求就会正常返回生成的key和url字段。
内容的提问来源于stack exchange,提问作者Joshua Maerker
相关产品推荐
相关产品推荐

