【问题标题】:Django Rest Framework ImageFieldDjango Rest 框架 ImageField
【发布时间】:2013-12-16 16:23:13
【问题描述】:

我无法将图像保存在此 ImageField 中。

发回数据时:

{
    "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

url.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 -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/

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:
    **
    Django Rest Framework Image Upload
    views.py
        class FileUploadView(APIView):
        permission_classes = []
        parser_class = (FileUploadParser,)
    
        @csrf_exempt
        def uploatuserprofile( request):
    
            #fetches specific user image
            if request.method=='GET':
                user_data=JSONParser().parse(request)
                obj=UserProfile.objects.filter(user=user_data["user"])
                serializer=UserProfileSerializer(obj,many=True)
                return JsonResponse(serializer.data,safe=False)
    
    
    
            if request.method == 'POST':
                # print('=====================================================================================>',request.FILES['profile_image'])
                
                # print("##################################################################################### ",request.POST['user'])
                try:
                    s = UserProfile.objects.create(user_id = request.POST['user'], profile_image=request.FILES['profile_image'])
                    s.save()
                except:
                    return JsonResponse('Failed to upload Integrity error',safe=False)
    
                
    
                # file_serializer=UserProfileSerializer(request.POST,request.FILES)
            
                # if file_serializer.is_valid():
                #     file_serializer.save()
                return JsonResponse('profile uploded Sucessfully!!',safe=False)
            return JsonResponse('Failed to upload',safe=False)
    
    urls.py of application
    
     url(r'^uploatuserprofile/$',views.FileUploadView.uploatuserprofile),
    
    
    urls.py of project
    from django.conf import settings
    from django.conf.urls.static import static
    
    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url,include
    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'^',include('ChatApp.urls'))
    ]
    if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL,
                              document_root=settings.MEDIA_ROOT)
    
    models.py
    
    class UserProfile(models.Model):
        user = models.ForeignKey(Users,on_delete=models.CASCADE)
        profile_image = models.ImageField(upload_to='images/', blank=True, null=True)
    
    
    
        def __str__(self):
            return self.profile_image.name
    
    
    
    
    
    setting.py
    
    STATIC_URL = '/images/'
    STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "images"),
    
    ]
    STATIC_DIR = os.path.join(BASE_DIR, 'images')
    # Base url to serve media files
    MEDIA_URL = '/media/'
    
    # Path where media is stored
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')`enter code here`**
    

    【讨论】:

    • 欢迎来到 StackOverflow。虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
    【解决方案2】:

    使用 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)
    

    希望对某人有所帮助。

    【讨论】:

    • 如何将图像上传到此实现@Orions?
    • @Pedrum 在我的回答中,我使用了 Django-Rest-Framework 的 serializer 作为模型:MyPhoto。当用户提交 post 请求时,Image 被上传或保存到模型中提到的路径(路径包括年、月和日文件夹)。如果还不清楚,请告诉我。
    • 我收到此错误 "detail": "Multipart form parse error - Invalid boundary in multipart: None"
    【解决方案3】:

    如果您要发布图片,以下应该可以工作 作为 base64 字符串,您的序列化程序相应设置,它继承了 serializer.Serializer

     # 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】:

      我认为您可以在django rest framework 3.0 之后使用request.datarequest.DATArequest.FILES 的用法现在正在等待弃用,取而代之的是包含所有已解析数据的单个 request.data 属性。

      您可以通过here查看它

      【讨论】:

      • 这行得通,顺便说一句,由于某种原因,您无法使用serializer.data['file_field'] 访问图像数据,您必须改用serializer.validated_data['file_field'] - 抓住了我,但在@ckman 的回答中发现了它!
      【解决方案5】:

      您的postput 处理程序中的序列化程序构造函数似乎缺少request.FILES 参数。

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

      【讨论】:

      猜你喜欢
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-19
      相关资源
      最近更新 更多