UpdateAPIView in Django not updating Image Field - python

In a Django Project I have simple UpdateAPIView
class ProfileUpdateAPIView(UpdateAPIView):
serializer_class = ProfileUpdateSerializer
authentication_classes = ( CsrfExemptSessionAuthentication, BasicAuthentication, TokenAuthentication,)
permission_classes = ((IsAuthenticated,))
and a simple model
def image_upload_fun(instance, filename):
return 'profile_pics/user_{0}.{1}'.format(str(instance.phone_number),filename.split(".")[1])
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,null=True, blank=True)
profile_pic = models.ImageField(upload_to=image_upload_fun, null=True, blank=True)
phone_number = models.CharField(max_length=12, unique=True, null=False, blank=False)
It does neither create new file nor it updates profile_pic_field.Although through admin panel it(image) gets updated or created easily
My request call is
Headers:
Authorization:Token 7554057effce1fcbc313f9a96be99ae17efb8eaf
Body:
phone_number:92123123132
profile_pic :[[my file]]
serializers.py
class ProfileUpdateSerializer(serializers.ModelSerializer):
profile_pic_url = serializers.SerializerMethodField()
class Meta:
model = Profile
fields = ["name", "email", "phone_number","gender", "date_of_birth", "profile_pic_url"]
def get_profile_pic_url(self, obj):
try:
return self.context["request"].build_absolute_uri("/").strip("/")+str(obj.profile_pic.url)
except Exception as E:
print(E)
return str("")

By default django-rest-framework uses JSONParsor. It will not parse uploaded files. To parse files we have to use MultiPartParser and FormParser like below
from rest_framework.parsers import MultiPartParser, FormParser
class ProfileUpdateAPIView(UpdateAPIView):
serializer_class = ProfileUpdateSerializer
authentication_classes = (
CsrfExemptSessionAuthentication,
BasicAuthentication,
TokenAuthentication
)
permission_classes = (IsAuthenticated,)
parser_classes = (MultiPartParser, FormParser)
Request using python requests
import requests
headers = {
"Content-Type": "multipart/form-data",
"Authorization": "Token <your token>"
}
data = {
"phone_number": "987654231",
"profile_pic": open("path/to/image.png", "r").read()
}
r = requests.post("http://localhost:8000/api/end-point/", data=data, headers=headers)
print(r.json())

I did a mistake in defining fields of ProfileUpdateSerializer
I didn't included profile_pic field in the fields of the serializer
Editing the serializer to add "profile_pic" field worked to upload image
class ProfileUpdateSerializer(serializers.ModelSerializer):
profile_pic_url = serializers.SerializerMethodField()
class Meta:
model = Profile
fields = ["name", "email", "phone_number","gender", "date_of_birth", "profile_pic","profile_pic_url"]
def get_profile_pic_url(self, obj):
try:
return self.context["request"].build_absolute_uri("/").strip("/")+str(obj.profile_pic.url)
except Exception as E:
print(E)
return str("")
I thought the serializer was just used to show a response after update.

Related

Django Rest Framework how do I get the id I use in the URL

I have this serializer and I use it to get post detail of a post belonging to a user. The owner of the post is not the user that is currently logged in. I want to check if the post is bookmarked by the currently logged in user. The currently logged in user's id is passed in the request but I cannot find it in this context.
Here is the serializer:
class UserPostSerializer(serializers.ModelSerializer):
images = PostImageSerializer(many=True, read_only=True, required=False)
profile = serializers.SerializerMethodField()
bookmarked = serializers.SerializerMethodField()
class Meta:
model = Post
fields = [
"id",
"category",
"body",
"images",
"video",
"profile",
"published",
"bookmarked",
"created_at",
"updated_at",
]
depth=1
def get_profile(self, obj):
profile_obj = Profile.objects.get(id=obj.user.profile.id)
profile = ShortProfileSerializer(profile_obj)
return profile.data
def get_bookmarked(self, obj):
breakpoint()
bookmark = Bookmark.objects.filter(owner=obj.user.id, post=obj.id,marktype='post')
if bookmark:
return True
else:
return False
The problem is obj.user.id is the owner of the post. I need the logged in user whose id is passed in the url. Here is the model for the bookmark:
class Bookmark(models.Model):
marktype = models.CharField(max_length=50)
post = models.OneToOneField(Post, on_delete=models.CASCADE, null=True, blank=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")
class Meta:
verbose_name = "bookmark"
verbose_name_plural = "bookmarks"
ordering = ["created_at"]
db_table = "bookmarks"
def __str__(self):
return "{}'s bookmark".format(self.owner.username)
and here is the URL:
path("posts/<int:user>/home/", HomeView.as_view(), name="home"),
This self.context['request'].user returns the owner of the post and not the logged in user.
How do I get the id of the currently logged in user or the user whose id I pass in the URL please?
Maybe do you can use filters to the Viewset:
urls.py
path("posts/home/", HomeView.as_view(), name="home")
viewsets.py
from rest_framework import viewsets
from .models import Post
from .serializers import, UserPostSerializer
from .filters import OwnerFilter
class HomeView(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = UserPostSerializer
filter_backends = (OwnerFilter,)
filters.py
from rest_framework.filters import BaseFilterBackend
class OwnerFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
owner = request.query_params.get('owner', None)
if not owner:
return queryset.all()
else:
try:
return queryset.filter(bookmarked__owner__id=owner)
except Exception:
return queryset.none()
Running
Then access the URL:
/posts/home/?owner=OWNER_ID_HERE
Solved it and you can get any kwargs from the view that handles the request. In my case adding the following to the get_bookmarked function gives me the id I send in the URL:
loggeduser = self.context.get('view').kwargs.get('user')

Django - Object of type User is not JSON serializable

I am facing an issue with POSTing data (which has a User object) to a ModelViewSet.
Error: "Object of type User is not JSON serializable"
data_params = {
"log_user_id": user,
"device_name": "sampledevice",
"log_user_email": "svc.netadc#ads.aexp.com",
"feature_name": 'Subnet Automation',
}
print(data_params, "data_params")
response = requests.post("<url>/netadc3/arista/ImplementationLogsAristaViewSet/implementationlogsarista/",
auth=(<username>, <password>), headers={"content-type": "application/json"}, data=json.dumps(data_params), verify=False)
serializers.py:
class ImplementationLogsAristaSerializer(serializers.HyperlinkedModelSerializer):
log_user_id = UserSerializer(read_only=True)
class Meta:
model = ImplementationLogsArista
fields = ('log_id','device_name', 'log_user_id','log_user_email','feature_name')
views.py:
class ImplementationLogsAristaViewSet(viewsets.ModelViewSet):
queryset = ImplementationLogsArista.objects.all()
serializer_class = ImplementationLogsAristaSerializer
permission_classes = (IsAuthenticated,)
pagination_class = None
models.py:
class ImplementationLogsArista(models.Model):
log_id = models.AutoField(primary_key=True)
device_name = models.CharField(max_length=800, verbose_name='Device Name',default='sampledevice')
log_user_id = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL, verbose_name='User ID')
log_user_email = models.CharField(max_length=500, verbose_name='User Email',default='admin')
feature_name = models.CharField(max_length=100, verbose_name='Feature Name',default='default_feature')
class Meta:
verbose_name = 'Implementation/Backout Logs'
verbose_name_plural = 'Implementation/Backout Logs'
def __unicode__(self):
return '%s %s %s %s %s' % (self.log_id,self.device_name,self.log_user_id,self.log_user_email,self.feature_name)
Not sure how to successfully POST the data with User into the ModelViewSet.
Probably, your user is Django User model instance, which is not JSON serializable:
data_params = {
"log_user_id": user, # <-- here
data=json.dumps(data_params) # <-- here
You should put user.pk in data_params:
data_params = {
"log_user_id": user.pk, # <-- here

Save reversal relationship item in database using one POST - Django

I want a viewset that handles a post request that creates some nested objects using the post data.
I have these models, serializers, and views:
Models:
class Connection(models.Model):
from portfolio.models import Portfolio
user = models.ForeignKey(User, related_name='exchange_connections', on_delete=models.CASCADE)
portfolios = models.ManyToManyField(Portfolio)
class ConnectionSettings(models.Model):
exchange_connection = models.OneToOneField(Connection, to_field='id', primary_key=True,
related_name='settings', on_delete=models.CASCADE)
import_past_transactions = models.BooleanField(default=False, blank=True)
class ConnectionCredentials(models.Model):
exchange_connection = models.OneToOneField(Connection, to_field='id', primary_key=True,
related_name='credentials', on_delete=models.CASCADE)
key = models.CharField(max_length=300, blank=False, null=False)
secret = models.CharField(max_length=300, blank=False, null=False)
passphrase = models.CharField(max_length=300, blank=True, null=True)
Serializers:
class ConnectionCredentialsSerializer(FlexFieldsModelSerializer):
class Meta:
model = ConnectionCredentials
fields = '__all__'
class ConnectionSettingsSerializer(FlexFieldsModelSerializer):
class Meta:
model = ConnectionSettings
fields = '__all__'
class ConnectionSerializer(serializers.ModelSerializer):
credentials = ConnectionCredentialsSerializer()
settings = ConnectionSettingsSerializer()
class Meta:
model = Connection
fields = '__all__'
def create(self, validated_data):
credentials = validated_data.pop('credentials')
settings = validated_data.pop('settings')
connection = Connection.objects.create(**validated_data)
ConnectionCredentials.objects.create(exchange_connection=connection, **credentials)
ConnectionSettings.objects.create(exchange_connection=connection, **settings)
return connection
Views:
class ConnectionViewSet(viewsets.ViewSet):
serializer_class = serializers.ConnectionSerializer
queryset = exchange_models.Connection.objects.all()
permission_classes = (IsAuthenticated, core_permissions.IsMineOnly)
def list(self):
return HttpResponse(self.request.user.exchange_connections_set)
def retrieve(self, request, pk=None):
serialized_data = self.serializer_class(exchange_models.Connection.objects.get(id=pk)).data
return HttpResponse(serialized_data)
def create(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
serializer.create(serializer.data)
serializer.save()
return Response({'status': 'connection created.'})
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
URLs:
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'connections', views.ConnectionViewSet)
urlpatterns = [
path('', include(router.urls)),
]
POST Request:
When I send the post request, the portfolios and the user already exist. So I should only give primary keys to these rows in my request.
But I need to create new rows for Settings and Credentials for which I should pass data in the request.
By default nested serializers are read-only. You will have to customize the create method to make it writable.
class ConnectionSerializer(serializers.ModelSerializer):
portfolios = PortfolioSerializer(many=True)
credentials = ConnectionCredentialsSerializer(many=False)
settings = ConnectionSettings(many=False)
class Meta:
model = models.Connection
exclude = ('user',)
read_only_fields = ('date_created', 'last_updated')
def create(self, validated_data):
portfolios = validated_data.pop('portfolios')
credentials = validated_data.pop('credentials')
settings = validated_data.pop('settings')
connection = Connection.objects.create(**validated_data)
for portfolio in portfolios:
Portfolio.objects.create(exchange_connection=connection, **portfolio)
for credential in credentials:
ConnectionCredentials.objects.create(exchange_connection=connection, **credentials)
for setting in settings:
ConnectionSettings.objects.create(exchange_connection=connection, **settings)
return connection
Provided that following are the model names relative to serializers.
PortfolioSerializer -> Portfolio,
ConnectionCredentialsSerializer -> ConnectionCredentials

Django set auto-user from context, user field not be null, JWT

In my case,I use JWT authentication, and when I create new "Post"(my model), I want automatically set author to user that request it.But when I do it, I got an error
{
"author": [
"This field is required."
]
}
I know,I'm not passing user, but I want to set it automatically, and I dont know how.
I just want to know how to avoid error, because when I pass value, that allows me to go ahead, the user is set automatically from context.
Serializer
class PostSerializer(FlexFieldsModelSerializer):
class Meta:
model = Post
fields = ('title','content',author','category','likedBy')
expandable_fields = {
'category': ('blogApi.CategorySerializer', {'many': True}),
'comments': ('blogApi.CommentSerializer', {'many': True}),
'likedBy': ('blogApi.LikedBySerializer', {'many': True}),
}
def create(self, validated_data):
user = self.context['request'].user
post = Post.objects.create(
author=user, title=validated_data['title'], content=validated_data['content'])
post.category.set(validated_data['category'])
return post
My create view
class PostCreate(generics.CreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticated]
Model
class Post(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
category = models.ManyToManyField(Category, related_name='posts')
author = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
likedBy = models.ManyToManyField(User, related_name='posts', blank=True)
class Meta:
ordering = ['-created']
def __str__(self):
return self.title
and when I create
You can make author a read-only field, or if you're just using this serializer to create users and not retreive them. You can just remove 'author' from fields in the serializer meta.
Read-only field
from rest_framework import serializers
class PostSerializer(FlexFieldsModelSerializer):
author = serializers.PrimaryKeyRelatedField(read_only=True)
class Meta:
model = Post
fields = ('title','content','author','category','likedBy')

How to upload multiple files in django rest framework

In django rest framework, I am able to upload single file using danialfarid/ng-file-upload
views.py:
class PhotoViewSet(viewsets.ModelViewSet):
serializer_class = PhotoSerializer
parser_classes = (MultiPartParser, FormParser,)
queryset=Photo.objects.all()
def perform_create(self, serializer):
serializer.save(blogs=Blogs.objects.latest('created_at'),
image=self.request.data.get('image'))
serializers.py:
class PhotoSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
models.py:
class Photo(models.Model):
blogs = models.ForeignKey(Blogs, related_name='blogs_img')
image = models.ImageField(upload_to=content_file_name)
When I try to upload multiple file. I get in
chrome developer tools:
Request Payload
------WebKitFormBoundaryjOsYUxPLKB1N69Zn
Content-Disposition: form-data; name="image[0]"; filename="datacable.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryjOsYUxPLKB1N69Zn
Content-Disposition: form-data; name="image[1]"; filename="datacable2.jpg"
Content-Type: image/jpeg
Response:
{"image":["No file was submitted."]}
I don't know how to write serializer for uploading multiple file.
I manage to solve this issue and I hope it will help community
serializers.py:
class FileListSerializer ( serializers.Serializer ) :
image = serializers.ListField(
child=serializers.FileField( max_length=100000,
allow_empty_file=False,
use_url=False )
)
def create(self, validated_data):
blogs=Blogs.objects.latest('created_at')
image=validated_data.pop('image')
for img in image:
photo=Photo.objects.create(image=img,blogs=blogs,**validated_data)
return photo
class PhotoSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
read_only_fields = ("blogs",)
views.py:
class PhotoViewSet(viewsets.ModelViewSet):
serializer_class = FileListSerializer
parser_classes = (MultiPartParser, FormParser,)
queryset=Photo.objects.all()
I dont know it very well, but this is working...
This is for my viewset.
def perform_create(self, serializer):
obj = serializer.save()
for f in self.request.data.getlist('files'):
mf = MyFile.objects.create(file=f)
obj.files.add(mf)
Here is how you upload multiple files on blogs api:
models.py
class Blogs(models.Model):
...
class Photo(models.Model):
blogs = models.ForeignKey(Blogs, related_name='blogs_img')
image = models.ImageField(upload_to=content_file_name)
serializers.py
class PhotoSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
fields = ['blogs', 'image',]
class BlogsSerializer(serializers.ModelSerializer):
photos = serializers.SerializerMethodField()
def get_photos(self, obj):
photos = Photo.objects.filter(blogs=obj)
return PhotoSerializer(photos, many=True, read_only=False).data
class Meta:
model = Blogs
fields = [
...
'photos',
]
views.py
class BlogsViewSet(viewsets.ModelViewSet):
serializer_class = BlogsSerializer
queryset = Blogs.objects.all()
def create(self, request, *args, **kwargs):
instance_data = request.data
data = {key: value for key, value in instance_data.items()}
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
instance = serializer.save()
if request.FILES:
photos = dict((request.FILES).lists()).get('photos', None)
if photos:
for photo in photos:
photo_data = {}
photo_data["blogs"] = instance.pk
photo_data["image"] = photo
photo_serializer = PhotoSerializer(data=photo_data)
photo_serializer.is_valid(raise_exception=True)
photo_serializer.save()
return Response(serializer.data)
I have solved the issue with this solution
models.py:
class Product(models.Model):
title = models.CharField(max_length=255)
description = models.CharField(max_length=255)
class Images(models.Model):
product = model.ForeignKey('Product', related_name="images", on_delete=models.CASCADE)
image = models.ImageField(upload_to=upload_path)
serializers.py
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = models.Images
fields = '__all__'
views.py
class ImagesViewSet(ModelViewSet):
queryset = models.Images.objects.all()
serializer_class = serializers.ImageSerializer
# overwrite create method from the CreateModelMixin
def create(self, request, *args, **kwargs):
data = request.data
images = data.getlist('image')
# if no images call parent method it will return error
if not images:
return super().create(request, *args, **kwargs)
# verify only without creating the images
serializer_lst = []
for image in images:
data['image'] = image
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
serializer_lst.append(serializer)
serializers_data = [] # this is to collect data for all created images and return as list in the response
for serializer in serializer_lst:
self.perform_create(serializer)
serializers_data.append(serializer.data)
headers = self.get_success_headers(serializer.data)
return Response(serializers_data, status=status.HTTP_201_CREATED, headers=headers)
It took me a while to find out an effective solution to this,
I would like to share with you what finally worked for me.
I am using reactjs and DRF.
Here is my model :
class MediaFile(models.Model):
article = models.ForeignKey(Articles, on_delete=models.CASCADE, null=True)
caption = models.CharField(max_length=500, null=True, blank=True)
file = models.FileField('photo of article', upload_to=set_filename,
blank=True, null=True, default='')
added = models.DateTimeField(auto_now_add=True)
The views are standard viewsets.ModelViewSet
class MediaFilesViewSet(viewsets.ModelViewSet):
serializer_class = FileListSerializer
parser_classes = (parsers.MultiPartParser, parsers.FormParser,)
queryset=MediaFile.objects.all()
In ArticleSerializer I added:
def create(self, validated_data):
request = self.context.get('request')
user = request.user
instance = Articles.objects.create(**validated_data)
instance.publisher = user
instance.save()
images = request.FILES
if images:
try:
for f in images.getlist('mediafiles'):
instance.mediafile_set.get_or_create(file=f, caption=f.name)
instance.save()
except Exception as e:
print(e)
return instance
The FRONTEND structure:
postChangeImage = (event) =>{
this.setState({
is_images: true
});
let files = event.target.files;
const files_array = Object.values(files);
this.setState(
{imagefile: files}
);
console.log('IMAGES ARRAY', files_array);
files_array.map(value => {
const urls = URL.createObjectURL(value);
this.setState((prevState)=>(
{postfolio:[urls, ...prevState.postfolio]}
));
});
};
and POSTING:
for (let i=0; i< this.state.imagefile.length; i++) {
form_data.append(`mediafiles`, this.state.imagefile[i]);
}
The best answer to this question did not work for me, but Charles' suggestion worked very well. In my case, I needed to upload multiple files and assign them to a specific batch. Each batch is assigned to a particular user.
Below is more context using ReactJS to make the POST request, along with the serializers used and Postman window:
api.py
from convert_files.models import File
from rest_framework import viewsets, permissions
from rest_framework.parsers import MultiPartParser, JSONParser
from .serializers import BatchSerializer
class BatchViewSet(viewsets.ModelViewSet):
permission_classes = [
permissions.IsAuthenticated
]
def perform_create(self, serializer):
obj = serializer.save(owner=self.request.user)
for f in self.request.data.getlist('files'):
mf = File.objects.create(office_file=f)
obj.files.add(mf)
parser_classes = (MultiPartParser, JSONParser, )
serializer_class = BatchSerializer
http_method_names = ['get','post','delete','put','patch', 'head']
def get_queryset(self):
return self.request.user.batches.all()
serializers.py
from rest_framework import serializers
from convert_files.models import File, Batch
class FileSerializer(serializers.ModelSerializer):
class Meta:
model = File
fields = '__all__'
class BatchSerializer(serializers.ModelSerializer):
files = FileSerializer(many=True, required = False)
class Meta:
model = Batch
fields = '__all__'
models.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from .extra import ContentTypeRestrictedFileField
def make_upload_path(instance, filename):
"""Generates upload path for FileField"""
return settings.OFFICE_OUTPUT_FILES_URL + "/%s" % (filename)
class Batch(models.Model):
name = models.CharField(max_length=100, blank=True)
description = models.TextField(blank=True)
date_posted = models.DateTimeField(default=datetime.datetime.now)
owner = models.ForeignKey(User, related_name="batches",
on_delete=models.CASCADE, null=True)
class File(models.Model):
name = models.CharField(max_length=100, blank=True)
office_file = ContentTypeRestrictedFileField(
upload_to = make_upload_path,
content_types = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.ms-excel','application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
max_upload_size = 10485760,
)
files = models.ForeignKey(Batch, on_delete=models.CASCADE, null=True,
related_name='files', related_query_name='files')
FileUpload.js
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { addBatch } from '../actions/batches';
function FileUpload() {
const dispatch = useDispatch();
let formData = new FormData()
const onDrop = useCallback((acceptedFiles) => {
for (var i = 0; i < acceptedFiles.length; i++) {
formData.append("files", acceptedFiles[i], acceptedFiles[i].name)
}
dispatch(addBatch(formData));
})
...
Postman
Image of POST request in Postman for Multiple File Upload to DRF
Working with "dictionary (array) of images"
Ok, so today I tried Arindam's solution.. it worked perfectly, but after a while, I figgured out that my frontend (port 3000) makes a GET request to itself looking for an image that is not there, and not at the backend(port 8000).. (eg. GET http://localhost:3000/media/images/products/default.png - Returns 404: Not found).. What worked for me was to change the code around a bit and this is my solution..
in models.py
class Product(models.Model):
title = models.CharField(max_length=255)
description = models.CharField(max_length=255)
price = models.FloatField()
quantity = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
slug = models.SlugField(max_length=255, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
...
class ProductImage(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='images')
image = models.ImageField("Image", upload_to=upload_to, default='products/default.png')
in serializers.py
...
class ProductImageSerializer(serializers.ModelSerializer):
class Meta:
model = ProductImage
fields = ['id', 'image', 'product']
extra_kwargs = {
'product': {'required': False},
}
class ProductSerializer(serializers.ModelSerializer):
images = ProductImageSerializer(many=True, required=False)
class Meta:
model = Product
fields = ['id', 'title', 'description', 'images', 'price', 'quantity', 'active', 'slug', 'created_at', 'modified_at']
read_only_fields = ['slug']
#lookup_field = 'slug'
def create(self, validated_data):
product = Product.objects.create(**validated_data)
try:
# try to get and save images (if any)
images_data = dict((self.context['request'].FILES).lists()).get('images', None)
for image in images_data:
ProductImage.objects.create(product=product, image=image)
except:
# if no images are available - create using default image
ProductImage.objects.create(product=product)
return product
in views.py
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
permission_classes = [permissions.AllowAny]
serializer_class = ProductSerializer
parser_classes = [MultiPartParser, FormParser]
#lookup_field = 'slug'
edit: in settings.py
import os
...
BASE_DIR = Path(__file__).resolve().parent.parent
...
MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/')
MEDIA_URL = '/media/'
I am posting this here to help someone (or me again in the future) with multiple files upload or multiple images upload as I spent 2 days looking up tutorials and answeres online to help me solve this issue... I may not be doing everything perfectly as I just recently started exploring Django REST Framework (and Python), but I hope it helps.

Categories

Resources