简体   繁体   English

DRF - M2M 通过 ImageField 的序列化程序提供 UnicodeDecodeError

[英]DRF - M2M through serializer for ImageField gives UnicodeDecodeError

I want to serialize a model using M2M through relation.我想通过关系使用 M2M 序列化模型。 Its working fine for all other fields except ImageField .它适用于除ImageField之外的所有其他领域。 Below are my model and serializer files:以下是我的模型和序列化程序文件:

models.py

class Product(models.Model):
    name = models.CharField('Name', max_length=255, null=True, blank=True)
    description = models.TextField('Description', max_length=1000, null=True, blank=True)
    price = models.IntegerField('Price', default=0)
    image = models.ImageField('Product Image', null=True, blank=True)


class Cart(models.Model):
    user = models.CharField('User ID', default="1000", max_length=255)
    items = models.ManyToManyField("Product", through='CartActions', blank=True)
    modified = models.DateField('Last Modified')


class CartActions(models.Model):
    product = models.ForeignKey('Product', on_delete=models.CASCADE)
    cart = models.ForeignKey('Cart', on_delete=models.CASCADE)
    quantity = models.PositiveSmallIntegerField(default=0)

serializers.py

class ProductSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'description', 'price', 'image']


class CartSerializer(serializers.HyperlinkedModelSerializer):
    items = CartActionsSerializer(source='cartactions_set', many=True)

    class Meta:
        model = Cart
        fields = ['id', 'user', 'items']


class CartActionsSerializer(serializers.HyperlinkedModelSerializer):
    name = serializers.ReadOnlyField(source='product.name')
    price = serializers.ReadOnlyField(source='product.price')
    image = serializers.ReadOnlyField(source='product.image')  # Adding this line gives error

    class Meta:
        model = CartActions
        fields = ['name', 'price', 'image', 'quantity']

This is the error I'm getting when hitting the API:这是我在访问 API 时遇到的错误:

UnicodeDecodeError at /store/api/cart/ /store/api/cart/处的 UnicodeDecodeError

'utf-8' codec can't decode byte 0xff in position 0: invalid start byte “utf-8”编解码器无法解码位置 0 中的字节 0xff:无效的起始字节

This is the sample response I'm getting from /api/products API:这是我从/api/products API 获得的示例响应:

{
    "id": 1,
    "name": "Product 1",
    "description": "This is a sample description",
    "price": 500,
    "image": "http://192.168.43.210:9000/media/sample_product.jpeg"
}

I've tried almost all references in stackoverflow and other websites but I cannot find the exact same issue anywhere.我已经尝试了 stackoverflow 和其他网站中的几乎所有参考资料,但我在任何地方都找不到完全相同的问题。

In this serializer you did not define field serializers explicitly, only mentioned field list:在这个序列化程序中,您没有明确定义字段序列化程序,只提到了字段列表:

class ProductSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'description', 'price', 'image']

DRF recognized image as an ImageField and applied serializers.ImageField serializer which has use_url argument: DRF image识别为 ImageField 并应用了具有use_url参数的serializers.ImageField 序列化程序:

use_url - If set to True then URL string values will be used for the output representation. use_url - 如果设置为 True,则 URL 字符串值将用于输出表示。 If set to False then filename string values will be used for the output representation.如果设置为 False,则文件名字符串值将用于输出表示。 Defaults to the value of the UPLOADED_FILES_USE_URL settings key, which is True unless set otherwise.默认为 UPLOADED_FILES_USE_URL 设置键的值,除非另有设置,否则为 True。

Thus it was serialized with ProductSerializer as an URL rather then binary picture or a filename.因此,它使用ProductSerializer作为 URL 而不是二进制图片或文件名进行序列化。

In the other serializer you have defined field serializer explicitly:在另一个序列化程序中,您明确定义了字段序列化程序:

class CartActionsSerializer(serializers.HyperlinkedModelSerializer):
    ...
    image = serializers.ReadOnlyField(source='product.image')

ReadOnlyField is a generic serializer which outputs source as it is . ReadOnlyField是一个通用的序列化器,它按原样输出source Thus 'product.image' returns an ImageField instance which is not an URL or path - it's the whole object with many attributes.因此,“product.image”返回一个不是 URL 或路径的 ImageField 实例——它是具有许多属性的整个对象。

So try using a specific field serializer所以尝试使用特定的字段序列化器

serializers.ImageField(read_only=True, ...)

or make source more specific with default to avoid errors if image is missing或者使用 默认值使源更具体,以避免图像丢失时出现错误

serializers.ReadonlyField(source='product.image.url', default=None, ...)

or access this value via method或通过方法访问此值

class CartActionsSerializer(serializers.HyperlinkedModelSerializer):
    ...
    image = serializers.SerializerMethodField()

    def get_image(self, obj):
        return obj.product.image.url

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM