更清晰的方法来序列化集合并处理具有多个模型实例的发布请求

时间:2017-03-20 04:06:50

标签: python json rest django-rest-framework serializer

我是DRF的新手,我一直试图向服务器发出POST请求。我希望每个请求都能发送多个联系人详细信息:

   {
      "firstName":"Ryan",
      "lastName":"Reynolds",
      "numbers":[
          1234567891, 9876543219
      ]
   }

......或类似的东西。

我的模特看起来像这样:

class Contact(models.Model):
firstName = models.CharField(max_length=50)
lastName = models.CharField(max_length=50)


class PhoneNumber(models.Model):
    contact = models.ForeignKey(Contact, related_name='numbers', on_delete=models.CASCADE)
    phoneNumber = models.CharField(max_length=10)

每个联系人都可以有多个电话号码,所以我写了这样的序列号:

class PhoneNumberSerializer(serializers.ModelSerializer):
    class Meta:
        model = PhoneNumber
        fields = ['phoneNumber']


class ContactSerializer(serializers.ModelSerializer):
    numbers = PhoneNumberSerializer(many=True)

    class Meta:
        model = Contact
        fields = ('firstName', 'lastName', 'numbers')

    def create(self, validated_data):
        numbers_data = validated_data.pop('numbers')
        contact = Contact.objects.create(**validated_data)

        for number_data in numbers_data:
            PhoneNumber.objects.create(contact=contact, **number_data)
        return contact

我的views.py看起来像这样:

class ContactView(APIView):

    def get(self, request, format=None):
        snippets = Contact.objects.all()
        serializer = ContactSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ContactSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

它接受这种格式的JSON ......

   {
      "firstName":"Ryan",
      "lastName":"Reynolds",
      "numbers":[
         {
            "phoneNumber":"6969666222"
         },
         {
            "phoneNumber":"2342342312"
         }
      ]
   }

......这不是我的想法。

我的问题是

  1. 我可以重写序列化程序/视图,以便能够以更干净的格式接受数字吗?也许是一系列数字,或者至少是一本包含所有数字的字典,而不是它现在的工作方式?
  2. 我想在同一个POST中发送多个联系人。因此,许多响应的数组结构类似于我在上面定义的响应,然后将每个响应作为单独的元素添加到数据库中。我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

使用以下更新代码

serializers.py

class PhoneNumberSerializer(serializers.ModelSerializer):
    class Meta:
        model = PhoneNumber
        fields = ['phoneNumber', 'contanct']


class ContactSerializer(serializers.ModelSerializer):
    numbers = PhoneNumberSerializer(many=True, read_only=True)

    class Meta:
        model = Contact
        fields = ('firstName', 'lastName', 'numbers')

    def create(self, validated_data):
        return Contact.objects.create(**validated_data)

views.py

class ContactView(APIView):
    def get(self, request, format=None):
        snippets = Contact.objects.all()
        serializer = ContactSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ContactSerializer(data=request.data)
        if serializer.is_valid():
            contact = serializer.save()
            numbers = request.data.get('numbers', '').split(',')
            new_data = []
            for number in numbers:
                temp = {}
                temp['phoneNumber'] = number
                temp['contact'] = contact.id
                new_data.append(temp)
            serializer = PhoneNumberSerializer(data=request.data, many=True)
            if serializer.is_valid():
                serializer.save()
            serializer = ContactSerializer(contact)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

它运作顺畅,但您仍需要在项目中尝试此解决方案,并让我知道它是否有效。

以下列方式传递数据:

{
    "firstName":"Ryan",
    "lastName":"Reynolds",
    "numbers": "1234567891,9876543219"
}