如何设置允许上传 JSON 数据和图像的 API?
How to setup an API which allows uploading JSON data and an image?
我用 Django REST Framework 构建了一个 API。以下视图集为客户端传输的 JSON 对象创建了一个数据库条目。
class ArticleViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
"""
API endpoint that allows articles to be created or viewed.
"""
queryset = Article.objects.all()
serializer_class = ArticleSerializer
现在,我想连同 JSON 数据一起发送 图像 。我想客户端必须将其请求作为 "multipart/form-data"
mime 类型发送。如有不妥请指正
因此,我添加了一个 MultiPartParser:
parser_classes = (MultiPartParser,)
为了在服务器端使用 ipdb 调试请求,我添加了 create
方法:
class ArticleViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
"""
API endpoint that allows articles to be created or viewed.
"""
queryset = Article.objects.all()
serializer_class = ArticleSerializer
parser_classes = (MultiPartParser,)
def create(request, *args, **kwargs):
ipdb.set_trace()
return Response(request)
如何实际检查request
是否收到数据?
经验教训
- 没有必要配置
MultiPartParser
因为它是 loaded by default。
- 我添加的
create
方法的签名是错误的。它必须是 create(self, request, *args, **kwargs)
。有了它,您将能够检查 request
对象和 request.data
。感谢 IRC 的 JockeTF #restframework !!
可以使用 cURL 从命令行发送测试请求,如下所示:
$ curl -vX POST http://localhost:8000/articles/ \
-H "Content-Type: multipart/form-data" \
-H "Accept:application/json" \
-F "title=Test" \
-F "author_name=cURL" \
-F "article_photo=@/home/user/Desktop/article-photo.png"
是的,您的客户应该这样做(js 示例)
var formdata = new FormData();
formdata.append("image", file);
在 Django 中,上传的文件可以在 request.FILES['image']
中访问
为此检查 Django 文档 https://docs.djangoproject.com/en/1.7/topics/http/file-uploads/
这是我所做的...
- 安装 Pillow package 进行图像处理
使用新属性扩展您的模型
article_photo = models.ImageField(blank=True)
在settings.py中配置以下设置:
对于开发环境:
ENV_PATH = os.path.abspath(os.path.dirname(__file__))
"""
Absolute filesystem path to the directory that
will hold user-uploaded files.
"""
MEDIA_ROOT = os.path.join(ENV_PATH, 'media/')
"""
Relative browser URL you should access your media files from
"""
MEDIA_URL = '/media/'
对于生产环境:
"""
Absolute filesystem path to the directory that
will hold user-uploaded files.
"""
MEDIA_ROOT = '/myapp/api/media'
"""
Relative browser URL you should access your media files from
Path must be served from webserver (Nginx, Apache, ..) configuration
"""
MEDIA_URL = '/myapp/media/'
创建新迁移并运行它。
$ python manage.py makemigrations
$ python manage.py migrate
使用cURL从命令行发送测试请求如下:
$ curl -vX POST http://localhost:8000/articles/ \
-H "Content-Type: multipart/form-data" \
-H "Accept:application/json" \
-F "title=Test" \
-F "author_name=cURL" \
-F "article_photo=@/home/user/Desktop/article-photo.png"
我用 Django REST Framework 构建了一个 API。以下视图集为客户端传输的 JSON 对象创建了一个数据库条目。
class ArticleViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
"""
API endpoint that allows articles to be created or viewed.
"""
queryset = Article.objects.all()
serializer_class = ArticleSerializer
现在,我想连同 JSON 数据一起发送 图像 。我想客户端必须将其请求作为 "multipart/form-data"
mime 类型发送。如有不妥请指正
因此,我添加了一个 MultiPartParser:
parser_classes = (MultiPartParser,)
为了在服务器端使用 ipdb 调试请求,我添加了 create
方法:
class ArticleViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
"""
API endpoint that allows articles to be created or viewed.
"""
queryset = Article.objects.all()
serializer_class = ArticleSerializer
parser_classes = (MultiPartParser,)
def create(request, *args, **kwargs):
ipdb.set_trace()
return Response(request)
如何实际检查request
是否收到数据?
经验教训
- 没有必要配置
MultiPartParser
因为它是 loaded by default。 - 我添加的
create
方法的签名是错误的。它必须是create(self, request, *args, **kwargs)
。有了它,您将能够检查request
对象和request.data
。感谢 IRC 的 JockeTF #restframework !! 可以使用 cURL 从命令行发送测试请求,如下所示:
$ curl -vX POST http://localhost:8000/articles/ \ -H "Content-Type: multipart/form-data" \ -H "Accept:application/json" \ -F "title=Test" \ -F "author_name=cURL" \ -F "article_photo=@/home/user/Desktop/article-photo.png"
是的,您的客户应该这样做(js 示例)
var formdata = new FormData();
formdata.append("image", file);
在 Django 中,上传的文件可以在 request.FILES['image']
中访问为此检查 Django 文档 https://docs.djangoproject.com/en/1.7/topics/http/file-uploads/
这是我所做的...
- 安装 Pillow package 进行图像处理
使用新属性扩展您的模型
article_photo = models.ImageField(blank=True)
在settings.py中配置以下设置:
对于开发环境:
ENV_PATH = os.path.abspath(os.path.dirname(__file__)) """ Absolute filesystem path to the directory that will hold user-uploaded files. """ MEDIA_ROOT = os.path.join(ENV_PATH, 'media/') """ Relative browser URL you should access your media files from """ MEDIA_URL = '/media/'
对于生产环境:
""" Absolute filesystem path to the directory that will hold user-uploaded files. """ MEDIA_ROOT = '/myapp/api/media' """ Relative browser URL you should access your media files from Path must be served from webserver (Nginx, Apache, ..) configuration """ MEDIA_URL = '/myapp/media/'
创建新迁移并运行它。
$ python manage.py makemigrations $ python manage.py migrate
使用cURL从命令行发送测试请求如下:
$ curl -vX POST http://localhost:8000/articles/ \ -H "Content-Type: multipart/form-data" \ -H "Accept:application/json" \ -F "title=Test" \ -F "author_name=cURL" \ -F "article_photo=@/home/user/Desktop/article-photo.png"