【问题标题】:How To Upload File with Django Rest APi如何使用 Django Rest APi 上传文件
【发布时间】:2014-08-16 00:55:53
【问题描述】:

有人可以帮助我如何在 django rest api 中使用 POST 方法上传文件, 例如当我启动时

curl -X POST 127.0.0.1:8000/api/v1/assets/ -d '{"name" = "my image   ","source"="/root/images/my_image2.jpg"}' -H "Content-Type: application/json"

我要上传 my_image2.jpg

serializers.py:

from django.forms import widgets
from rest_framework import serializers
from .models import Asset

class AssetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Asset

views.py:

from .serializers import AssetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from rest_framework import status
from rest_framework.decorators import api_view


class AssetAdd(APIView):


    def post(self, request, format=None):
        serializer = AssetSerializer(data=request.DATA)
        print serializer.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)

模型.py

class Asset(models.Model):

    key = models.CharField(max_length=8, unique=True, editable=False)
    name = models.CharField(_('name'), max_length=200)
    source = models.FileField(_('file'), upload_to=upload_to, storage=default_storage)

    ext = models.CharField(max_length=15, editable=False)
    type = models.PositiveIntegerField(choices=ASSET_TYPE, max_length=15, editable=False)
    size = models.PositiveIntegerField(max_length=32, default=0, editable=False)

    _file_meta = models.TextField(editable=False, null=True, blank=True)

    public = models.BooleanField(default=False)
    position = models.PositiveIntegerField(default=1)

    object_id = models.PositiveIntegerField(default=1)
    content_type = models.ForeignKey(ContentType, blank=True, null=True)
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now_add=True, auto_now=True)

我是 Django REST API 的新手,我阅读了文档 http://www.django-rest-framework.org/api-guide/parsers.html#fileuploadparser,但仍然不明白如何去做

【问题讨论】:

标签: django rest django-rest-framework


【解决方案1】:

首先你需要在你的视图中定义一个解析器。这是因为 API 需要知道要查找哪些标头。浏览器将文件作为表单数据传输,因此您需要同时使用 MultiPartParser 和 FormParser。您也可以使用 FileUploadParser,但您需要确保您的客户端发送正确的 HTTP 标头。

from rest_framework.parsers import MultiPartParser, FormParser

class AssetAdd(APIView):
    parser_classes = (MultiPartParser, FormParser,)

然后,在 post 方法中,您的文件将出现在 FILES QueryDict 中:

def post(self, request, format=None):
    my_file = request.FILES['file_field_name']
    filename = '/tmp/myfile'
    with open(filename, 'wb+') as temp_file:
        for chunk in my_file.chunks():
            temp_file.write(chunk)

    my_saved_file = open(filename) #there you go

【讨论】:

  • 请您详细解释一下,
  • 我添加了类 AssetAdd(APIView): parser_classes = (MultiPartParser, FormParser,) def post(self, request, format=None): my_file = request.FILES['file_field_name'] print my_file跨度>
  • 当我尝试执行 {"name": "San Francisco Bridge", "source": "assets/34/3492/3492AA/3492AA/source.jpg"} 时,出现错误 {"详细信息”:“多部分表单解析错误 - 多部分中的边界无效:无”}
  • 我试过 curl -X POST 127.0.0.1:8000/api/v1/assets -d '{"name": "San Francisco Bridge", "source": "assets/34/3492/3492AA/3492AA/source.jpg" }' -H "Content-Type: multipart/form-data" 但是得到错误 { "detail": "Multipart form parse error - Invalid boundary in multipart: None" } ???
  • @MarkWinterbottom from rest_framework.parsers import MultiPartParser, FormParser
【解决方案2】:

这样写你的模型:

from django.db import models
class PicModel(models.Model):
    file_to_be_uploaded = models.FileField(upload_to='/directory/where/you/what/to/upload/to')

如果你上传图片然后 ImageField 但安装枕头pip install pillow。

在你serializers.py 假设你正在使用rest_framework:

from rest_framework import serializers
from app_name.models import PicModel

class PicSerializer(serializers.ModelSerializer):
    class Meta:
        model = PicModel
        fields = '__all__' #or any way you may like to display you fields

在您views.py 中包含假设您要使用基于类的视图:

from app_name.models import PicModel
from app_name.serializers import PicModelSerializer
#other necessary imports

class PicList(APIView):
    def post(self, request, format=None):#or format can be json or api
        serializer = PicModelSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            ............more code

在 json 数据中进行测试,如下所示:

{
    "file_to_be_uploaded":"//path//to//file//on//local//machine"
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2013-04-01
    • 1970-01-01
    相关资源
    最近更新 更多