首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >to_representation采用两种不同的值类型

to_representation采用两种不同的值类型
EN

Stack Overflow用户
提问于 2020-01-28 17:24:10
回答 1查看 847关注 0票数 2

我不太理解to_reprsentation(self, value),我有个这样的案子

使用

  • 状态时,返回"ORDERED,.“当我发布并创建订单,而int
  • when中的valueto_reprsentation类型时,打开localhost:8000/orders/,我得到Order对象不能转换为intvalueOrder类型。

我搜索了我找到的每一篇文章,我没有理解to_representationto_internal_value这两种方法

models.py

代码语言:javascript
复制
class Product(models.Model):
    title = models.CharField(max_length=120)
    price = models.FloatField(max_length=20)

    def __str__(self):
        return f"{self.title} - {self.price}"

    class Meta:
        ordering = ['price']

    @property
    def images(self):
        for image in Image.objects.filter(product=self):
            yield image.src.url

代码语言:javascript
复制
class STATUS:
    UNORDERED = 0
    ORDERED = 1
    BEING_PROCESSED = 2
    BEING_DELIVERED = 3
    DELIVERED = 4
    RECEIVED = 5
    REFUND_REQUESTED = 6

代码语言:javascript
复制
class Order(models.Model):
    ORDER_STATUS = (
        (STATUS.UNORDERED, 'Unordered'),
        (STATUS.ORDERED, 'Ordered'),
        (STATUS.BEING_PROCESSED, 'Being processed'),
        (STATUS.BEING_PROCESSED, 'Being Delivered'),
        (STATUS.DELIVERED, 'Delivered'),
        (STATUS.RECEIVED, 'Received'),
        (STATUS.REFUND_REQUESTED, 'Refund requested')
    )

    products = models.ManyToManyField(Product)  #
    status = models.IntegerField(choices=ORDER_STATUS, default=STATUS.UNORDERED)

    class Meta:
        ordering = ['pk']

serializers.py

代码语言:javascript
复制
class ProductSerializer(serializers.ModelSerializer):
    images = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = ['id', 'title', 'price', 'images']

    def get_images(self, obj):
        request = self.context.get('request', None)
        for url in obj.images:
            yield request.build_absolute_uri(url)


class StatusField(serializers.RelatedField):
    def to_internal_value(self, value):
        try:
            if int(value) > STATUS.ORDERED:
                raise APIException("Can't update an ordered order.")
        except ValueError:
            raise APIException('Unknown order status code')
        except TypeError:
            raise APIException('Order status must be an integer.')
        return value

    def to_representation(self, value):
        if isinstance(value, Order):
            return value.status if value.status <= STATUS.ORDERED else APIException('Hi')
        # if int(value) == 0:
        #     return "Unordered"
        # elif int(value) == 1:
        #     return "Ordered"
        # elif int(value) == 2:
        #     return "Being processed"
        # elif int(value) == 3:
        #     return "Being Delivered"
        # elif int(value) == 4:
        #     return "Delivered"
        # elif int(value) == 5:
        #     return "Received"
        # elif int(value) == 6:
        #     return "Refund requested"
        # raise serializers.ValidationError('Invalid order status code')


class OrderSerializer(serializers.ModelSerializer):
    products = ProductSerializer(many=True)
    status = StatusField(queryset=Order.objects.all())

    class Meta:
        model = Order
        fields = ['id', 'status', 'products']
        depth = 2

    def create(self, validated_data):  # needs auth
        products_list = validated_data.pop('products')
        order = Order.objects.create(**validated_data)
        for product_data in products_list:
            product = Product.objects.create(**product_data)
            order.products.add(product)
        order.save()
        return order

    def update(self, instance, validated_data):
        products_data = validated_data.pop('products')

        if instance.status >= STATUS.ORDERED:
            raise APIException("Can't update an ordered order")

        instance.status = validated_data.get('status', instance.status)

如果我使用If isInstance,它将工作,但我确实想知道为什么有时它返回Order,而另一些时候它返回int

医生说The value argument will typically be a model instance.,而这在我的情况下并没有发生。

我遗漏了什么?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-28 22:09:22

序列化程序文档中描述的字段用于自定义关系字段。这就是为什么文档通常说正在输入一个模型实例。status字段用于serializers.IntegerField,而不是serializers.RelationField

不需要为状态验证继承单独的StatusField。相反,您可以使用validate_<fieldname>函数。验证是在保存时完成的。

代码语言:javascript
复制
class OrderSerializer(serializers.ModelSerializer):
    def validate_status(self, value):
        try:
            if int(value) > STATUS.ORDERED:
                raise APIException("Can't update an ordered order.")
        except ValueError:
            raise APIException('Unknown order status code')
        except TypeError:
            raise APIException('Order status must be an integer.')
        return value

博士:https://www.django-rest-framework.org/api-guide/serializers/#field-level-validation

另外,在django 3.0中,您可以使用models.IntegerChoices。如果您使用django 3.0,可以考虑使用它。博士:https://docs.djangoproject.com/en/3.0/ref/models/fields/#enumeration-types

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59954050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档