0

I am pretty stuck working with DRF for the first time. I am looking to upload multiple Images to a single real estate Listing.

My image model

class Image(models.Model):      
    photo = models.ImageField(blank=True, upload_to=get_image_filename)
    listing = models.ForeignKey(Listing, on_delete=models.CASCADE)

my Image, Listing, and Listing detail serializers

class ListingSerializer(serializers.HyperlinkedModelSerializer):      
    image_set = ImageSerializerForListingDetail(many=True, required=False)

    class Meta:                  
        model = Listing                  
        fields = ['url', 'address', 'image_set', ]   

class ListingDetailSerializer(serializers.HyperlinkedModelSerializer):          
    user = AccountSerializer(read_only=True)          
    image_set = ImageSerializerForListingDetail(many=True, required=False)      

    class Meta:                  
        model = Listing                  
        fields = '__all__'                  
        depth = 1   

class ImageSerializerForListingDetail(serializers.ModelSerializer):          
image_url = serializers.SerializerMethodField()      

    class Meta:                  
        model = Image                  
        fields = ('image_url', ) 

    def get_image_url(self, listing): 
        return listing.photo.url 

My view

class ListingViewSet(viewsets.ModelViewSet):          
    queryset = Listing.objects.all()          
    serializer_class = ListingSerializer              
    detail_serializer_class = ListingDetailSerializer          
    permission_classes = [IsOwnerOrReadOnly, ]       

    '''Show detailed Listing view'''      
    def get_serializer_class(self):          
        if self.action == 'retrieve':              
            if hasattr(self, 'detail_serializer_class'):              
                return self.detail_serializer_class                  
        return super(ListingViewSet, self).get_serializer_class() 

I am having trouble figuring out how to upload/edit multiple Images, to a single Listing, and where to override. I would like it possible when both creating and editing listings. Any help is greatly appreciated. Thanks!

master_j02
  • 377
  • 3
  • 13

2 Answers2

0

This specific use case does have a section dedicated in the docs for "Writable nested objects"

https://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations

If you're supporting writable nested representations you'll need to write .create() or .update() methods that handle saving multiple objects.

The doc should cover the appropriate example you are looking for!

jcirni
  • 57
  • 4
  • if you would like another example, I just implemented this on a recent project. You can model yours around my __InspectionSerializer__ class https://github.com/jcirni/risk_api/blob/master/inspection_reporter/risk_api/serializers.py – jcirni Feb 25 '20 at 18:24
0

It seems like this should do the trick, and then I still need to work on the update method.

class ListingSerializer(serializers.HyperlinkedModelSerializer):
    user = UsernameSerializer(read_only=True)
    image_set = ImageSerializerForListingDetail(many=True, required=False, 
                                                read_only=True)

    class Meta:
        model = Listing
        exclude = ('url', )
        depth = 1

    def create(self, validated_data):
        images_data = validated_data.pop('image_set')
        listing = Listing.objects.create(**validated_data)
        for image_data in images_data:
            Image.objects.create(listing=listing, **image_data)
        return listing

Is there anything special that needs to me done with Images, that my one big concern? I always thought I needed to request.FILES, but I am seeing that that has been depreciated in DRF 3?

master_j02
  • 377
  • 3
  • 13