【问题标题】:The submitted data was not a file. Check the encoding type on the form in DRF 3提交的数据不是文件。检查 DRF 3 中表单上的编码类型
【发布时间】:2015-12-13 05:44:45
【问题描述】:

输出错误

{
 "item_image": [
    "The submitted data was not a file. Check the encoding type on the form."
],
"item_thumb": [
    "The submitted data was not a file. Check the encoding type on the form."
]
}

我发布的数据是

输入

{
    "item_name": "Lural",
    "item_image": "/home/prashant/Desktop/suede.png",
    "item_thumb": "/home/prashant/Desktop/suede.png",
    "item_description": "sd",
    "item_mass": 1,
    "item_category": "Make Up",
    "item_sub_category": "Sub-Feminine",
    "item_est_price": "123.12",
    "item_wst_price": "120.34"
}

对于媒体类型application/json

views.py

@api_view(['GET', 'POST'])
def product_list(request):
    if request.method == 'POST':
        serializer = ProductSerializer( data=request.data)
        # data.encode("base64")
        if serializer.is_valid():
            serializer.save()
            res_msg = {'Success_Message' : 'Created','Success_Code' : 201}
            return Response(res_msg)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

models.py

class Product(models.Model):
    item_category_choices = (
        ('Make Up','Make Up'),
        ('Skin Care','Skin Care'),
        ('Fragrance','Fragrance'),
        ('Personal Care','Personal Care'),
        ('Hair Care','Hair Care'),
    )
    item_name = models.CharField(max_length=50)
    item_image = models.ImageField()
    item_thumb = models.ImageField()
    item_description = models.TextField(max_length=200)
    item_mass = models.IntegerField()
    item_category = models.CharField(max_length=20,choices = item_category_choices)
    item_sub_category = models.CharField(max_length=20)
    item_est_price = models.DecimalField(max_digits=15,decimal_places=2)
    item_wst_price = models.DecimalField(max_digits=15,decimal_places=2)

    def __unicode__(self):
        return self.item_name or _('Sprint ending %s')% self.item_avg_price

serializers.py

class ProductSerializer(ModelSerializer):

    class Meta:
        model = Product
        fields = ('id','item_name' ,'item_image','item_thumb','item_description','item_mass','item_category',
              'item_sub_category','item_est_price','item_wst_price',)

也尝试了许多论坛和第三方软件包,但他们并没有解决这个问题。 GET 也运行良好。

感谢您的宝贵时间

【问题讨论】:

  • 嘿,你找到解决这个问题的方法了吗?
  • 我也在寻找解决方案。有人找到了吗?

标签: python django django-models django-rest-framework


【解决方案1】:

来自 Django 文档 -

如果您打算允许用户上传文件,您必须确保 用于运行 Django 的环境配置为使用非 ASCII 文件名。如果您的环境配置不正确,您将 用文件保存文件时遇到UnicodeEncodeError异常 包含非 ASCII 字符的名称。

因此将这个方法添加到模型中解决了我的问题:

class Product(models.Model):
item_category_choices = (
    ('Make Up','Make Up'),
    ('Skin Care','Skin Care'),
    ('Fragrance','Fragrance'),
    ('Personal Care','Personal Care'),
    ('Hair Care','Hair Care'),
    )
item_name = models.CharField(max_length=50,verbose_name='Product Name')
item_image = models.ImageField(verbose_name='Product Image')
item_thumb = models.ImageField(verbose_name='Product Thumb')
item_description = models.TextField(verbose_name='Product Descriptions')
item_mass = models.CharField(max_length=10,verbose_name='Product Weight')
item_category = models.CharField(max_length=20, choices = item_category_choices,verbose_name='Product Category')
item_sub_category = models.CharField(max_length=20,verbose_name='Product Sub Category')
item_est_price = models.DecimalField(max_digits=12,decimal_places=2,verbose_name='East Product Price')
item_wst_price = models.DecimalField(max_digits=12,decimal_places=2,verbose_name='West Product Price')
def __unicode__(self):
            return (self.item_name)
def image_img(self):
    if self.item_image:
        return u'<img src="%s" width="50" height="50" />' % self.item_image.url
    else:
        return '(Sin imagen)'
image_img.short_description = 'Thumb'
image_img.allow_tags = True

【讨论】:

  • 我仍然收到此错误:{"image":["Upload a valid image. The file you uploaded was either not an image or a corrupted image."]}
  • 你在drf的内容部分添加了文件的位置吗??
  • 我还检查了 python shell 中的文件系统编码,它支持 UFT-8 文件名..
  • 你是否在url中添加了路径,也尝试通过管理员添加图像并检查它是否工作正常。
  • 这是 DRF 2.4.4 中的一个错误,在 3.0 及其后续版本中已修复。 urls 必须添加在 urls.py 上传的图像通常添加在媒体中,并且它们的路径在 urls 中给出。
【解决方案2】:

您应该按如下方式打开图像并发送请求:

with open("/home/prashant/Desktop/suede.png", 'rb') as image:
    data = {'item_name': 'Lural',
            'item_image': image,
            'item_thumb': image,
            'item_description': 'sd',
            'item_mass': 1,
            'item_category': 'Make Up',
            'item_sub_category': 'Sub-Feminine',
            'item_est_price': '123.12',
            'item_wst_price': '120.34'
            }
    response = api.client.put(url, data, format='multipart')

这应该可行!

【讨论】:

  • 如何在django rest框架的内容部分添加这个??
  • 我陷入了完全相同的境地。您可能会看到stackoverflow.com/q/35884951/5080347 作为参考。我为 django rest 框架附上了一些快照。在 drf 的内容部分,我以与该问题的 OP 相同的方式添加了数据,即我在图像字段中给出了文件的位置,但它不起作用。您建议需要先打开文件然后发送请求。我不知道如何在 drf 中做到这一点,即在内容部分中打开文件,然后仅在内容部分中发送请求。我希望我现在很清楚。 :)
  • 我不想在我的views.py 文件中添加这段代码。我只想在 django rest 框架中发送原始数据。谢谢
【解决方案3】:

您无需提交指向文件"/home/prashant/Desktop/suede.png" 的链接,而是实际打开文件并提交。

例如,这里有一个测试我要测试图片提交:

 # generate image and open
tmp_file = Image.new('RGB', (3, 3,), 'white')
tmp_file.putpixel((1, 1,), 0)
tmp_file.save(f.name, format='PNG')
_file = open(f.name, 'rb')


data = {'file': _file}

response = api.client.put(url=url, data=data)

【讨论】:

  • 您能否详细说明您的答案。这会很有帮助。谢谢
  • 我试过你的解决方案,但是 response.status_code 是 400,应该是 201
  • @djq 如何在django rest框架的内容部分添加这个?
猜你喜欢
  • 2016-10-31
  • 2019-04-30
  • 1970-01-01
  • 2021-09-30
  • 2020-08-30
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多