2013-05-13 2 views
8

Potrzebuję otrzymać obraz z aplikacji, a najlepszym sposobem, jaki mogę wymyślić, jest wysłanie go do tablicy JSON zakodowanej w Base64. Obraz jest bardzo mały, więc nie dbam o dodatkowy narzut.Odbiór zakodowanego obrazu Base64 w środowisku Django Rest Framework i zapisanie w ImageField

Mam model:

class Observation(models.Model):  
    ... 
    sonogram_image = models.ImageField(upload_to=sonogram_dir) 

I jego serialiser:

class ObsvSerializerNoDetect(serializers.HyperlinkedModelSerializer): 

    class Meta: 
     model = Observation 

Gdzie należy umieścić kod dekodować obraz?

+0

Czy kiedykolwiek to wymyśliłeś? –

+0

Tak i nie. Przechowuję obraz jako tekst, a następnie renderowanie go na stronie internetowej jest dość łatwe, w znaczniku 'img' umieszczasz' src = "data: image/png; base64, . Nie jestem pewien, czy to najlepszy sposób, ale działa dobrze i jest łatwy do wdrożenia. – gozzilli

+0

@gozzilli możesz zapewnić najszerszy dostęp do widoku/serializera/modeli rozwiązania opartego na base64? – andi

Odpowiedz

1

Nie może być dwie najlepsze lokalizacje, w zależności od przypadków użycia:

  1. w serializatora masz validate_X i transform_X metody można przesłonić dla danej dziedzinie (patrz validation docs) i do nawrócenia w obu kierunkach tutaj.

  2. jeśli chcesz częściej korzystać z tej funkcji, napisz własną custom field. Musisz tylko zdefiniować sposób konwersji w obu kierunkach w to_native i from_native. Być może przedłużyć oryginalny DRF ImageField, aby zachować walidację danych obrazu za pomocą PIL.

4

Oto jak można obsługiwać plik obrazu zakodowany w Base64 w żądaniu postu na końcu API opartym na Django (DRF), który zapisuje go jako ImageField.

powiedzmy masz model następująco:

Class MyImageModel(models.Model): 
     image = models.ImageField(upload_to = 'geo_entity_pic') 
     data=model.CharField() 

Więc analogicznym serializer będzie następująco:

from drf_extra_fields.fields import Base64ImageField 

Class MyImageModelSerializer(serializers.ModelSerializers): 
     image=Base64ImageField() 
     class meta: 
     model=MyImageModel 
     fields= ('data','image') 
     def create(self, validated_data): 
     image=validated_data.pop('image') 
     data=validated_data.pop('data') 
     return MyImageModel.objects.create(data=data,image=image) 

Odpowiedni View może być następująca:

elif request.method == 'POST': 
    serializer = MyImageModelSerializer(data=request.data) 
    if serializer.is_valid(): 
     serializer.save() 
     return Response(serializer.data, status=201) 
    return Response(serializer.errors, status=400) 

Uwaga W Serializatorze wykorzystałem implementację Base64ImageField dostępną w module django-extra-field

Aby zainstalować ten moduł uruchomić polecenie

pip install django-extra-fields 

import samo i Gotowe!

Wyślij (metodą pocztową) obraz jako zakodowany ciąg Base64 w obiekcie JSON wraz z innymi posiadanymi danymi.