2013-11-24 3 views
5

일부 API 끝점을 노출하기 위해 DRF를 사용하고 있습니다.Django Rest Framework PrimaryKeyRelatedField를 사용하여 중첩 된 객체를 반환합니다.

# 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의 목록을 게시 할 수 있습니다. 그러나이 기능을 사용하려면 RelatedField 대신 PrimaryKeyRelatedField을 사용해야했습니다. 즉, 내가 GET을 수행하면 assigned_to 필드에 사용자의 기본 키만 수신된다는 것을 의미합니다. POST의 현재 동작을 유지하지만 assigned_to 필드의 일련 번호 User 세부 정보를 반환하는 방법이 있습니까?

답변

3

이 경우 POSTGET에 다른 serializer를 사용해야합니다.

보기에서 get_serializer_class() 메서드를 재정의하고 self.request.method에 따라 반환되는 serializer를 전환하십시오.

+0

그래서, 나는 get_serializer_class() 메소드를 재정의하는 시도 :'데프 get_serializer_class (자기) : 인쇄 self.request.method; if self.request.method == "GET": ...'그러나 runserver에서'POST '를 보았을 때조차도 요청은 항상'GET'입니다. –

2

최근에 입력을위한 id를 사용하여 값을 설정하지만 직렬자를 사용하여 중첩 된 값을 반환하는 하위 클래스 PrimaryKeyRelatedField()으로이 문제를 해결했습니다. 이제는 여기에서 요청한 것이 100 %가 아닐 수도 있습니다. POST는 PrimaryKeyRelatedField와 똑같이 POST가 동작하는 반면 POST, PUT 및 PATCH 응답에는 중첩 된 표현이 포함됩니다.

https://gist.github.com/jmichalicek/f841110a9aa6dbb6f781

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 
관련 문제