Reputation: 15470
I have this really simple Django-Rest-Framework task app which does now behave the way I expect.
Both image and file upload work so does the url routing their urls. However when I upload only Doc
to new Task
I get following error >
{
"image": [
"The submitted data was not a file. Check the encoding type on the form."
]
}
Note that I just added the blank=True
field behaviour was same without it. the default No-img.jpg and No-doc.pdf files exist and route fine.
Here is my TaskApp/models.py
from django.db import models
class Task(models.Model):
task_name = models.CharField(max_length=20)
task_desc = models.TextField(max_length=200)
completed = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True, auto_created=True)
image = models.ImageField(upload_to='Images/', default='Images/None/No-img.jpg', blank=True)
doc = models.FileField(upload_to='Doc/', default='Doc/None/No-doc.pdf')
def __str__(self):
return '{}'.format(self.task_name)
# TODO try to understand why this model requires image upload
Here is my TaskApp/serializers.py
from rest_framework import serializers from .models import Task
class TaskSerializer(serializers.ModelSerializer):
image = serializers.ImageField(max_length=None, use_url=True)
doc = serializers.FileField(max_length=None, use_url=True)
class Meta:
model = Task
fields = ('id', 'task_name', 'task_desc', 'completed', 'date_created', 'image', 'doc')
Here is my TaskApp/views.py
from rest_framework import viewsets, filters from .models import Task from .serializers import TaskSerializer
class TaskViewSet(viewsets.ModelViewSet):
queryset = Task.objects.all() # We use filters for ordering by part
serializer_class = TaskSerializer
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter, filters.SearchFilter)
filter_fields = ('completed',)
ordering = ('-date_created',)
search_fields = ('task_name',)
Here is my TaskAPI/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework import routers
from TaskApp import views
from django.conf.urls.static import static
from django.conf import settings
router = routers.DefaultRouter()
router.register(r'task', views.TaskViewSet)
# router.register(r'due_task', views.DueTaskViewSet)
# router.register(r'completed_task', views.CompletedTaskViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^admin/', admin.site.urls),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I am not sure why this behaves the way it does. Any help is highly appreciated.
Upvotes: 0
Views: 2544
Reputation: 599708
The problem is your serializer. You have overridden the definitions for image
and doc
; as with ModelForms, when you redefine a field in a model serializer you redefine all its options; including, in this case, whether it is required. You will need to declare that explicitly:
class TaskSerializer(serializers.ModelSerializer):
image = serializers.ImageField(max_length=None, use_url=True, required=False)
doc = serializers.FileField(max_length=None, use_url=True)
Upvotes: 4