简体   繁体   English

使用请求库将图像上传到 Django Rest 框架

[英]Upload an Image to Django Rest Framework using Requests Library

I am trying to make an api endpoint for creating a post, the user can choose whether they want to upload a text(tweet) or an image alone or both, I have a validate method in my serializer for if no image nor text is sent, but it's raising the error on every try regardless if what I sent it.我正在尝试制作一个 api 端点来创建帖子,用户可以选择是否要上传文本(推文)或单独上传图像或两者,我的序列化程序中有一个验证方法,如果没有发送图像或文本,但无论我发送的是什么,它都会在每次尝试时引发错误。 Am not entirely sure if this is a serializer class error or the script I wrote for sending the POST request我不完全确定这是序列化程序 class 错误还是我为发送 POST 请求而编写的脚本

  • Here is the script:这是脚本:
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)
  • Here's the model class:这是 model 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]

  • Here's the serializer class:这是序列化器 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
  • Here are my views:以下是我的看法:
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)

when I run the python script to send the request I always get the validation error saying content or an image must be provided当我运行 python 脚本发送请求时,我总是收到验证错误,提示必须提供内容或图像

You have to check if there is a file via the view's request.FILES attribute.您必须通过视图的 request.FILES 属性检查是否有文件。 The file you posted would not be in the POST body.您发布的文件不会在 POST 正文中。

If there is no file posted, the request.FILES attribute will be an empty list.如果没有发布文件,则 request.FILES 属性将是一个空列表。

Here is how you can do it: (Note that in CreateAPIView's create method, serializer already has the request object in its context)以下是您的操作方法:(请注意,在 CreateAPIView 的 create 方法中,序列化程序已经在其上下文中包含请求 object)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM