Django Rest框架使用PrimaryKeyRelatedField返回嵌套对象
我正在使用DRF公开一些API端点Django Rest框架使用PrimaryKeyRelatedField返回嵌套对象,django,django-rest-framework,Django,Django Rest Framework,我正在使用DRF公开一些API端点 # models.py class Project(models.Model): ... assigned_to = models.ManyToManyField( User, default=None, blank=True, null=True ) # serializers.py class ProjectSerializer(serializers.ModelSerializer): assig
# models.py
class Project(models.Model):
...
assigned_to = models.ManyToManyField(
User, default=None, blank=True, null=True
)
# serializers.py
class ProjectSerializer(serializers.ModelSerializer):
assigned_to = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(), required=False, many=True)
class Meta:
model = Project
fields = ('id', 'title', 'created_by', 'assigned_to')
# view.py
class ProjectList(generics.ListCreateAPIView):
mode = Project
serializer_class = ProjectSerializer
filter_fields = ('title',)
def post(self, request, format=None):
# get a list of user.id of assigned_to users
assigned_to = [x.get('id') for x in request.DATA.get('assigned_to')]
# create a new project serilaizer
serializer = ProjectSerializer(data={
"title": request.DATA.get('title'),
"created_by": request.user.pk,
"assigned_to": assigned_to,
})
if serializer.is_valid():
serializer.save()
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.data, status=status.HTTP_201_CREATED)
这一切都很好,我可以发布分配给字段的ID列表。然而,为了实现这个功能,我必须使用
PrimaryKeyRelatedField
而不是RelatedField
。这意味着当我执行GET
时,我只会在assigned_to
字段中接收用户的主键。是否有某种方法可以维护POST
的当前行为,但返回assigned\u to
字段的序列化User
详细信息?在这种情况下,您需要为POST
和GET
使用不同的序列化程序
查看覆盖视图上的
get\u serializer\u class()
方法,并根据self.request.method
切换返回的序列化程序。我最近用一个子类PrimaryKeyRelatedField()
解决了这个问题,该子类使用id作为输入来设置值,但使用序列化程序返回嵌套值。现在这可能不是这里要求的100%。POST、PUT和PATCH响应也将包括嵌套表示,而问题确实指定POST的行为与PrimaryKeyRelatedField完全相同
因此,我尝试重写get_serializer_class()方法:
def get_serializer_class(self):print self.request.method;如果self.request.method==“GET”:…
但是请求总是GET
,即使我在runserver中看到POST
。
class PrimaryKeyInObjectOutRelatedField(PrimaryKeyRelatedField):
"""
Django Rest Framework RelatedField which takes the primary key as input to allow setting relations,
but takes an optional `output_serializer_class` parameter, which if specified, will be used to
serialize the data in responses.
Usage:
class MyModelSerializer(serializers.ModelSerializer):
related_model = PrimaryKeyInObjectOutRelatedField(
queryset=MyOtherModel.objects.all(), output_serializer_class=MyOtherModelSerializer)
class Meta:
model = MyModel
fields = ('related_model', 'id', 'foo', 'bar')
"""
def __init__(self, **kwargs):
self._output_serializer_class = kwargs.pop('output_serializer_class', None)
super(PrimaryKeyInObjectOutRelatedField, self).__init__(**kwargs)
def use_pk_only_optimization(self):
return not bool(self._output_serializer_class)
def to_representation(self, obj):
if self._output_serializer_class:
data = self._output_serializer_class(obj).data
else:
data = super(PrimaryKeyInObjectOutRelatedField, self).to_representation(obj)
return data