Prashant Shukla
Prashant Shukla

Reputation: 762

The submitted data was not a file. Check the encoding type on the form in DRF 3

OutputError

{
 "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."
]
}

Data which I'm posting is

input

{
    "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"
}

for media type 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',)

tried many forums & third party packages too but their isn't any way out from this problem. Also GET is working totally fine.

Thanks for your time

Upvotes: 13

Views: 16020

Answers (3)

Prashant Shukla
Prashant Shukla

Reputation: 762

From Django Docs -

If you intend to allow users to upload files, you must ensure that the environment used to run Django is configured to work with non-ASCII file names. If your environment isn’t configured correctly, you’ll encounter UnicodeEncodeError exceptions when saving files with file names that contain non-ASCII characters.

Thus adding this method to the model solved my problem :

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

Upvotes: 4

vabada
vabada

Reputation: 1814

You should open the image and send the request as follows:

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')

This should work!

Upvotes: 1

djq
djq

Reputation: 15286

Instead of submitting a link to a file "/home/prashant/Desktop/suede.png", you need to actually open the file and submit that instead.

For example, here is a test I have to test image submission:

 # 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)

Upvotes: 2

Related Questions