Reputation: 140
I want to upload image from react frontend. I tested the api from DRF browsable API, it worked as expected.
#views.py
class CreatePost(CreateAPIView):
permission_classes = (permissions.AllowAny, )
queryset = BlogPost.objects.all()
serializer_class = BlogCreateSerializer
#serializers.py
class BlogCreateSerializer(serializers.ModelSerializer):
class Meta:
model = BlogPost
fields = ('id', 'title', 'category', 'thumbnail',
'excerpt', 'content', 'author')
On the react side
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
<div className="form-group">
<label htmlFor="exampleFormControlFile1">THUMBNAIL</label>
<input
type="file"
className="form-control-file"
name="thumbnail"
value={thumbnail}
onChange={(e) => onChange(e)}
required
/>
</div>
headers: {
"Content-type": "multipart/form-data",
},
And as for errors: in console response JSON
detail "Multipart form parse error - Invalid boundary in multipart: None"
in console request.payload
{"title":"dkjhksnc","category":"environment","thumbnail":"C:\\fakepath\\80dbf456adfc4e5499f86b04de37fad5.jpg","excerpt":"ewfewgrf ","content":"efewfewgw","author":"1"}
I am new to both DRF and react. Please see how can I upload "thumbnail" field for my blog posts.
If you need any other details please comment.
Upvotes: 2
Views: 1035
Reputation: 61
function onImageSelected(e) {
const formData = new FormData()
// It probably won't work if the file name doesn't include the image extension especially if you're using ImageField in your django model
formData.append('image', e.currentTarget.files[0], 'image.png')
// I am using axios, you could use XMLHttpRequest if you want
// You don't have to specify Content-Type headers yourself, they will be inferred from the data passed in.
axios.post('your_endpoint', formData)
.then((res)=> {// Success}).catch((err)=> {// Failure})
}
The default django rest framework configuration handles both json and form data, so you don't have to do anything.
Say that this is your endpoint:
@api_view(['POST'])
def my_view(request):
s = MySerializer(request.data)
s.is_valid(raise_exception=True)
s.save()
That's it. You could use ImageField
or FileField
on your model to store the image. Note that it actually only stores the url and uploads your image to your storage backend whether it's the file system (default) or any other backend like amazon s3 or google cloud storage. Look django-storages
library for more information.
The file system is only suitable for development. In order to use it, you need to set MEDIA_URL
and MEDIA_ROOT
in your settings file:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
That's it. If you want to be able to preview the images through your browser during development, you need to add this to your urls.py
as shown here
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Upvotes: 2