2013-11-24 17 views
5

Tôi đang sử dụng DRF để hiển thị một số điểm cuối API.Django Rest Framework trả về đối tượng lồng nhau bằng cách sử dụng 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) 

Tất cả đều hoạt động tốt và tôi có thể ĐĂNG danh sách id cho trường được chỉ định. Tuy nhiên, để thực hiện chức năng này, tôi phải sử dụng PrimaryKeyRelatedField thay vì RelatedField. Điều này có nghĩa là khi tôi thực hiện GET thì tôi chỉ nhận được các khóa chính của người dùng trong trường assigned_to. Có cách nào để duy trì hành vi hiện tại cho POST nhưng trả lại chi tiết User được tuần tự hóa cho trường assigned_to không?

Trả lời

3

Bạn cần phải sử dụng trình nối tiếp khác cho POSTGET trong trường hợp đó.

Xem xét phương pháp get_serializer_class() trên chế độ xem và chuyển bộ nối tiếp được trả về tùy thuộc vào self.request.method.

+0

Vì vậy, tôi đã cố gắng trọng phương pháp get_serializer_class(): 'def get_serializer_class (tự): print self.request.method; nếu self.request.method == "GET": ... 'nhưng yêu cầu luôn là' GET', ngay cả khi tôi thấy một 'POST' trong máy chủ lưu trữ. –

2

Gần đây tôi đã giải quyết vấn đề này với một lớp con được phân loại là PrimaryKeyRelatedField() sử dụng id cho đầu vào để đặt giá trị, nhưng trả về giá trị lồng nhau bằng cách sử dụng serializers. Bây giờ điều này có thể không được 100% những gì được yêu cầu ở đây. Các phản hồi POST, PUT và PATCH cũng sẽ bao gồm biểu diễn lồng nhau trong khi câu hỏi không chỉ rõ rằng POST hoạt động chính xác như với một PrimaryKeyRelatedField.

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 
Các vấn đề liên quan