2

I am trying to save files uploaded to a Django Rest Framework 3.0 API using the Angular plugin ng-file-upload. This is a very popular plugin in Angular, which for reasons of browser purity is a total pain when it comes to uploading.

That plugin requires that the file is called "file" in the headers, so on the Django side I am trying to associate that "file" with the correct field in the model, which happens to be "photo".

I am trying to use DRF's new perform_update hook to copy the uploaded "file" across to the "photo" field. But, alas, I can't do it. Either my Python is wrong at some very basic level (which is the likely answer), or the serializer object in the perform_update hook is read only, or something. Nothing I do to the serializer object seems to make a scrap of difference, and I am unable to save the file.

Incidentally, I can save the file fine using DRF's own web interface. Just not with my own Angular app.

Relevant Django:

class Entity(models.Model):
  name = models.CharField("Entity Name", max_length=100, unique=True)
  description = models.TextField(blank=True)
  photo = models.ImageField(blank=True,upload_to='entity_images')

class EntityViewSet(UnCachedModelViewSet):
  queryset = Entity.objects.all().order_by('name')
  filter_fields = ('user','slug')
  # parser_classes = (MultiPartParser,) #makes no difference

  def perform_update(self, serializer):
    if 'file' in self.request.data:
        serializer.data['photo'] = self.request.data['file']
        print('SERIALIZER: ',serializer.data) #for test purposes only
    serializer.save()

Whatever I do to serializer.data, it looks the same when I print it in the next line, as if it's read-only or something. In any event, the file never saves to the photo field.

Am I approaching this all wrong? How do you use perform_update?

PS the basic approach to the Angular=>Django file upload conundrum came from here, but the DRF pre_save hook used in that solution has been replaced by perform_update in the latest version of DRF, as per here.

APPENDING TO INCLUDE THE WORKING ANSWER:

def perform_update(self, serializer):
    if 'file' in self.request.data:
        serializer.save(photo= self.request.data['file'])
    else:
        serializer.save()
Community
  • 1
  • 1
John
  • 5,581
  • 6
  • 29
  • 46

1 Answers1

2

Try this:

serializer.save(photo=self.request.data['file'])

And Let me know....

Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
jatinkumar patel
  • 2,920
  • 21
  • 28
  • I had tried that one already. The thing that is stumping me is, the print of serializer.data (also a print of json.dumps(serializer.data)) doesn't show anything being assigned to serializer.data at all. I can't figure out how to change any fields in serializer.data, even text ones that should be simple to change. `serializer.data['name'] = 'foo'` doesn't change the name, for instance. – John May 03 '15 at 10:42