使用请求库将图像上传到 Django Rest Framework
Upload an Image to Django Rest Framework using Requests Library
我正在尝试创建一个 api 端点来创建 post,用户可以选择是否要单独上传文本(推文)或图片或两者,我有一个如果没有发送图像或文本,我的序列化程序中的验证方法,但无论我发送的是什么,它都会在每次尝试时引发错误。
我不完全确定这是序列化程序 class 错误还是我为发送 POST 请求
编写的脚本
- 这是脚本:
import os
import requests
from PIL import Image
ENDPOINT = "http://0.0.0.0:8000/"
IMG = os.path.join(os.getcwd(), "img/img.jpg")
def send_request(method="GET", path="/", data=None, img_path=None):
if data is None:
data = {}
if img_path is not None:
with open(img_path, 'rb') as image:
img_file = {"image": image}
req = requests.request(method, ENDPOINT + path, data=data, files=img_file)
else:
req = requests.request(method, ENDPOINT + path, data=data)
return req.text
res = send_request(method="POST", path="api/posts/create/", data={"user": 1, "content": ""}, img_path=IMG)
print(res)
- 这是模型 class:
from django.db import models
from django.conf import settings
import uuid
import os
class PostQuerySet(models.QuerySet):
pass
class PostManager(models.Manager):
def get_queryset(self):
return PostQuerySet(self.model, using=self._db)
def upload_post_image(instance, filename):
file_extension = filename.split('.')[-1]
filename = f"{uuid.uuid4()}.{file_extension}"
print(os.path.join())
return os.path.join('post_image/', filename)
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField(null=True, blank=True, max_length=255)
image = models.ImageField(null=True, upload_to=upload_post_image)
def __str__(self):
return str(self.content)[:50]
- 这是序列化器 class:
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.Serializer):
class Meta:
model = Post
fields = ('user', 'content', 'image')
def validate(self, data):
content = data.get("content", None)
image = data.get("image", None)
if content == '':
content = None
if image is None and content is None:
raise serializers.ValidationError("Content or an Image must be provided")
return data
- 以下是我的观点:
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import generics, mixins, permissions, authentication
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import PostSerializer
from .models import Post
class PostManageAPIView(
APIView,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.CreateModelMixin,
mixins.ListModelMixin):
def get(self, request, *args, **kwargs):
print(self.request.GET)
return Response({"message": "This is just a test"})
class PostDetailAPIView(generics.RetrieveAPIView):
serializer_class = PostSerializer
permission_classes = ()
authentication_classes = ()
queryset = Post.objects.all()
def get_object(self, *args, **kwargs):
kwargs = self.kwargs
kw_id = kwargs.get('id')
try:
return Post.objects.get(id=kw_id)
except ObjectDoesNotExist:
return Response({})
class CreatePost(generics.CreateAPIView):
serializer_class = PostSerializer
permission_classes = ()
authentication_classes = ()
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
当我 运行 python 脚本发送请求时,我总是收到验证错误,提示必须提供内容或图像
您必须通过视图的 request.FILES 属性检查是否有文件。您发布的文件不会在 POST 正文中。
如果没有文件发布,request.FILES 属性将为空列表。
您可以这样做:(请注意,在 CreateAPIView 的创建方法中,序列化程序的上下文中已经有请求对象)
class PostSerializer(serializers.Serializer):
class Meta:
model = Post
fields = ('user', 'content', 'image')
def validate(self, data):
content = data.get("content", None)
request = self.context['request']
# you dont need to set content explicitly to None
if not request.FILES and not content:
raise serializers.ValidationError("Content or an Image must be provided")
return data
我正在尝试创建一个 api 端点来创建 post,用户可以选择是否要单独上传文本(推文)或图片或两者,我有一个如果没有发送图像或文本,我的序列化程序中的验证方法,但无论我发送的是什么,它都会在每次尝试时引发错误。 我不完全确定这是序列化程序 class 错误还是我为发送 POST 请求
编写的脚本- 这是脚本:
import os
import requests
from PIL import Image
ENDPOINT = "http://0.0.0.0:8000/"
IMG = os.path.join(os.getcwd(), "img/img.jpg")
def send_request(method="GET", path="/", data=None, img_path=None):
if data is None:
data = {}
if img_path is not None:
with open(img_path, 'rb') as image:
img_file = {"image": image}
req = requests.request(method, ENDPOINT + path, data=data, files=img_file)
else:
req = requests.request(method, ENDPOINT + path, data=data)
return req.text
res = send_request(method="POST", path="api/posts/create/", data={"user": 1, "content": ""}, img_path=IMG)
print(res)
- 这是模型 class:
from django.db import models
from django.conf import settings
import uuid
import os
class PostQuerySet(models.QuerySet):
pass
class PostManager(models.Manager):
def get_queryset(self):
return PostQuerySet(self.model, using=self._db)
def upload_post_image(instance, filename):
file_extension = filename.split('.')[-1]
filename = f"{uuid.uuid4()}.{file_extension}"
print(os.path.join())
return os.path.join('post_image/', filename)
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField(null=True, blank=True, max_length=255)
image = models.ImageField(null=True, upload_to=upload_post_image)
def __str__(self):
return str(self.content)[:50]
- 这是序列化器 class:
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.Serializer):
class Meta:
model = Post
fields = ('user', 'content', 'image')
def validate(self, data):
content = data.get("content", None)
image = data.get("image", None)
if content == '':
content = None
if image is None and content is None:
raise serializers.ValidationError("Content or an Image must be provided")
return data
- 以下是我的观点:
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import generics, mixins, permissions, authentication
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import PostSerializer
from .models import Post
class PostManageAPIView(
APIView,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.CreateModelMixin,
mixins.ListModelMixin):
def get(self, request, *args, **kwargs):
print(self.request.GET)
return Response({"message": "This is just a test"})
class PostDetailAPIView(generics.RetrieveAPIView):
serializer_class = PostSerializer
permission_classes = ()
authentication_classes = ()
queryset = Post.objects.all()
def get_object(self, *args, **kwargs):
kwargs = self.kwargs
kw_id = kwargs.get('id')
try:
return Post.objects.get(id=kw_id)
except ObjectDoesNotExist:
return Response({})
class CreatePost(generics.CreateAPIView):
serializer_class = PostSerializer
permission_classes = ()
authentication_classes = ()
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
当我 运行 python 脚本发送请求时,我总是收到验证错误,提示必须提供内容或图像
您必须通过视图的 request.FILES 属性检查是否有文件。您发布的文件不会在 POST 正文中。
如果没有文件发布,request.FILES 属性将为空列表。
您可以这样做:(请注意,在 CreateAPIView 的创建方法中,序列化程序的上下文中已经有请求对象)
class PostSerializer(serializers.Serializer):
class Meta:
model = Post
fields = ('user', 'content', 'image')
def validate(self, data):
content = data.get("content", None)
request = self.context['request']
# you dont need to set content explicitly to None
if not request.FILES and not content:
raise serializers.ValidationError("Content or an Image must be provided")
return data