Reputation: 2457
So I have this class:
class MyClass(models.Model):
name = models.CharField(max_length=100)
created_time = models.DateTimeField(auto_now_add = True)
modified_time = models.DateTimeField(auto_now = True)
and then other class representing related photos to MyClass:
class MyPhoto(models.Model):
myclass = models.ForeignKey(MyClass, unique=False, related_name='photos')
photo = models.ImageField(upload_to='photos',blank=False)
I would like to create an endpoint, which will handle photo uploads (content type will be multipart and id of associted myclass will be passed in url), so this is what I have:
urls.py:
router = routers.DefaultRouter()
router.register(r'photos/(?P<myclass_id>\d+)',PhotoViewSet)
viewset:
class PhotoViewSet(CreateModelMixin,
viewsets.GenericViewSet):
queryset = MyPhoto.objects.all()
serializer_class = serializers.PhotoAlterSerializer
parser_classes = (parsers.MultiPartParser,)
def create(self, request, *args,**kwargs):
myclass = MyClass.objects.get(pk=kwargs['myclass_id'])
serializer = serializers.PhotoAlterSerializer(data=request.data,context={'request': request})
if serializer.is_valid(raise_exception=True):
photo=serializer.save(myclass=myclass)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
and serializer:
class PhotoAlterSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MyPhoto
fields = ('myclass','photo')
as you can see Im adding additional attribute myclass to the serializer.save(myclass=myclass) method.
However if I upload photo and correctly pass myclass id in url, I get This field is required. error. If I add correct hyperlink to the myclass into uploaded multipart form with photo, request will pass validation and then myclass from form will be replaced by myclass I got from url id.
How can I make this work, so if I post only photo to the url http://blabla/api/photos/2 the instance of this photo and myclass with pk=2 will be saved to db?
Upvotes: 2
Views: 2982
Reputation: 4775
This is because you specified myclass
in the fields meta of your serializer. This makes DRF requires and validates it as part of the POST data. Any field that you would set yourself should not be part of the serializer fields. So, all you need to make it work is to remove myclass
from Meta.fields
.
class PhotoAlterSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MyPhoto
fields = ('photo', )
Upvotes: 1