webentwicklung-frage-antwort-db.com.de

Django Rest Framework ImageField

Ich kann das Bild in diesem ImageField nicht speichern.

beim Zurücksenden von Daten:

{
    "image": ["No file was submitted. Check the encoding type on the form."]
}

model.py

class MyPhoto(models.Model):
    owner = models.ForeignKey('auth.User', related_name='image')
    image = models.ImageField(upload_to='photos', max_length=254)

serializers.py

class PhotoSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyPhoto
        fields = ('url', 'id', 'image', 'owner')
        owner = serializers.Field(source='owner.username')

view.py

class PhotoList(APIView):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)

    def get(self, request, format=None):
        photo = MyPhoto.objects.all()
        serializer = PhotoSerializer(photo, many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request, format=None):
       serializer = PhotoSerializer(data=request.DATA)
       if serializer.is_valid():
           serializer.save()
           return Response(serializer.data, status=status.HTTP_201_CREATED)
       return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def pre_save(self, obj):
        obj.owner = self.request.user


class PhotoDetail(APIView):

    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)

    def get_object(self, pk):
        try:
            return MyPhoto.objects.get(pk=pk)
        except MyPhoto.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        photo = self.get_object(pk)
        serializer = PhotoSerializer(photo)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        photo = self.get_object(pk)
        serializer = PhotoSerializer(photo, data=request.DATA)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        photo = self.get_object(pk)
        photo.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    def pre_save(self, obj):
        obj.owner = self.request.user

rl.py

urlpatterns = patterns('',
    url(r'^$', 'main.views.main_page'),
    url(r'^api/photo/$', views.PhotoList.as_view(), name='myphoto-list'),
    url(r'^api/photo/(?P<pk>[0-9]+)/$', views.PhotoDetail.as_view(), name='myphoto-detail'),)

Curl

curl -X POST -S \
  -H 'Content-Type: application/json' \
  -u "michael:bush_pass" \
  --data-binary '{"owner":"/users/1/", \
    "image":"/Users/test/Downloads/1383310998_05.jpg"}' \
  127.0.0.1:8000/api/photo/
36
M.Hoffa

Ihnen scheint das Argument request.FILES Für den Serializer-Konstruktor in den Handlern post und put zu fehlen.

serializer = PhotoSerializer(data=request.DATA, files=request.FILES)
23
Kevin Stone

Ich denke, Sie können stattdessen request.data Nach Django rest framework 3.0 Verwenden. Die Verwendung von request.DATA Und request.FILES Ist jetzt veraltet, und zwar zugunsten eines einzelnen Attributs request.data, Das alle analysierten Daten enthält.

Sie können es von hier überprüfen

36
Scofield77

Hochladen von Bilddateien mit Django Rest Framework:

models.py:

class MyPhoto(models.Model):
    name = models.CharField(max_length=255)
    image = models.ImageField(upload_to='myphoto/%Y/%m/%d/', null=True, max_length=255)

serializers.py:

class MyPhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyPhoto
        fields = ('id', 'name', 'image')

views.py:

class PhotoList(APIView):
    def post(self, request, format=None):
        serializer = MyPhotoSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Hoffe es hilft jemandem.

9
Ajeet Shah

Das Folgende sollte funktionieren, wenn Sie das Bild als Base64-Zeichenfolge veröffentlichen und Ihr Serializer entsprechend eingestellt ist und es serializer.Serializer erbt

 # views.py 
import base64
import os
from Django.core.files import File 

class PhotoList(APIView):
    def post(self,request,format=None):
        serializer = PhotoSerializer(data=request.data)
        if serializer.is_valid():
            # access the data as serializer.validated_data['keys']
            # save the MyPhoto obj lets call it myphoto
            # get the base64 string 
            imgstr64 = serializer.validated_data['corresponding filed in the serializer']
            imgdata = base64.b64decode(imgstr64)
            fname = '/tmp/%s.jpg'%(str(myphoto.id))
            with open(fname,'wb') as f:
                f.write(imgdata)
            imgname = '%s.jpg'%(str(myphoto.id))
            myphoto.image.save(imgname,File(open(fname,'r')))
            os.remove(fname)
4
chandan