如何通过序列化器发布数组数据?

时间:2019-04-03 07:21:13

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

我想通过序列化器的create方法发布一些数组数据。如何在序列化器的create方法中获取数组数据?

这是我的结果,由于数组数据而产生错误。我必须发布以下特殊的,inch_first ... rate数组数据。

{
    "order_media": {
        "client_employee": "4",
        "client": "63",
        "narration": "Print ad",
        "vendor": "68",
        "total_amount": "2590.00",
        "discount_rate_client": "10.00",
        "discount_amount_client": "259.00",
        "service_percentage": "10.00",
        "service_amount": "259.00",
        "client_vat": "388.50",
        "total_receivable": "2978.50",
    },
    "pub_date": "2019-04-03",
    "particular": ["Banner", "Poster", "Plastic banner"],
    "inch_first": ["4", "5", "3"],
    "inch_second": ["4", "5", "3"],
    "size": ["16.00", "25.00", "9.00"],
    "quantity": ["5", "5", "6"],
    "rate": ["10", "10", "10"],
}

这是我的模特

class RequestPrintProduction(models.Model):
    particular = models.CharField(max_length=255,null=True,blank=True)
    inch_first = models.CharField(max_length=45,null=True,blank=True)
    inch_second = models.CharField(max_length=45,null=True,blank=True)
    size = models.CharField(max_length=45,blank=True, null=True)
    quantity = models.CharField(max_length=45,null=True, blank=True)
    rate = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal(0.00), null=True, blank=True)
    pub_date = models.DateField(blank=True, null=True)
    vendor = models.ForeignKey(Party, blank=True, null=True)
    request_id = models.ForeignKey(Request, blank=True, null=True, related_name='requestprint')

    def __str__(self):
        return self.particular

这是我的api视图:

class PrintRequestAPIView(ListBulkCreateAPIView):
    serializer_class = RequestPrintSerializer

这是我的序列化器:

class RequestPrintSerializer(serializers.ModelSerializer):
    order_media = OrderMediaSerializer(required=False)

    class Meta:
        model = RequestPrintProduction
        fields = '__all__'

    def create(self, validated_data):
        service_request = Request()
        service_request.save()

        validated_data['request_id'] = service_request
        order_media = validated_data.pop('order_media')
        print(order_media)

        online_service_request = self.Meta.model.objects.create(**data)

        order_media['request_id'] = service_request
        order_media = OrderMedia.objects.create(**order_media)

        return online_service_request

我希望成功发布数组的数据。

2 个答案:

答案 0 :(得分:0)

似乎您的数据库中有一个char字段,但想将数组发布到DRF。实际上,正如评论所提到的,这几乎是您所有领域的问题。您似乎可以通过在各处传递字符串来解决此问题。

如果没有数据库支持,则无法直接使用。但是,如果您确实要这样做,那么您将不得不在自己的代码中完成一些工作。可能有 个自定义字段,但我从未见过它们。

仅JSON发布

这是执行此操作的一种简单方法:

  1. 直接将序列化器上的字段声明为ListField
  2. 在“验证”功能中,转换为字符串(csv,json.dumps等)
  3. 请注意,我不是要检查空值,设置默认值等。请自行阅读ListField的文档(和源代码)。
class Serializer(ModelSerializer):
    particular = ListField(child=CharField(max_length=10))

    def validate_particular(self, value):
        """Convert the list to a json string, and do extra validation if needed"""
        return json.dumps(value)

输入和输出(发布并获取)

如果您将其同时用于输入和输出,并且想从模型中返回列表,则需要创建一个自定义字段:

class ListAsJsonField(fields.ListField):
    """
    Converts an incoming list of string values to json.
    This field is _very_ primitive, lots of edge cases may break it.
    """
    child = fields.CharField(min_length=1) # always use a char field

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def to_representation(self, data):
        """Convert to our output representation.  Assumes input is always valid json now"""
        return json.loads(data)

    def to_internal_value(self, data):
        """Convert to the internal value -> database (and validated_data)"""
        return json.dumps(data)

class MySerializer(serializers.ModelSerializer):
    particular = ListAsJsonField(required=True, min_length=1)
    ...

注意:

某些数据库(例如postgres)具有自定义JSON字段和Array字段。 Django随附django.contrib.postgres中的字段。使用这些意味着您还想解决其他模型问题。

ListBulkCreateAPIView到底是什么?

答案 1 :(得分:0)

让我们尝试如下安排帖子数据。然后,每当为此请求初始化RequestPrintSerializer时,都要用many = True初始化序列化程序。希望能帮助到你。好运气。

{
  "order_media": {
    "client_employee": "4",
    "client": "63",
    "narration": "Print ad",
    "vendor": "68",
    "total_amount": "2590.00",
    "discount_rate_client": "10.00",
    "discount_amount_client": "259.00",
    "service_percentage": "10.00",
    "service_amount": "259.00",
    "client_vat": "388.50",
    "total_receivable": "2978.50"
  },
  "request_print_production": [
    {
      "pub_date" : "2019-04-03",
      "particular": "Banner",
      "inch_first": "4",
      "inch_second": "4",
      "size": "16.00",
      "quantity": "5",
      "rate": "10"
    },
    {
      "pub_date" : "2019-04-03",
      "particular": "Poster",
      "inch_first": "5",
      "inch_second": "5",
      "size": "25.00",
      "quantity": "5",
      "rate": "10"
    },
    {
      "pub_date" : "2019-04-03",
      "particular": "Plastic Banner",
      "inch_first": "3",
      "inch_second": "3",
      "size": "9.00",
      "quantity": "6",
      "rate": "10"
    }
  ]
}
相关问题