首页 > 解决方案 > 即使在创建帖子期间使用 Postman 将文件上传到该字段后,Django Rest Framework 仍显示字段错误

问题描述

我是 DRF 的新手,我有这个序列化程序,但我无法创建帖子,因为即使在将图像上传到该字段后,它仍然在邮递员中向我显示这个。在普通的 django 中,这个 PostImage 模型与 Post 有一个外键关系,我使用一个表单集来上传多个图像。

{
"postimage": [
    "This field is required."
    ]
}

有人可以帮我解决这个问题并告诉我它是如何工作的吗?

序列化程序.py

class PostImageSerializer(serializers.ModelSerializer):
   class Meta:
       model = PostImage
       fields = ['id','post', 'images',]  

class PostCreateSerializer(serializers.ModelSerializer):
    postimage = PostImageSerializer(many=True)
    class Meta:
        model = Post
        fields = ['id','title', 'image', 'postimage',]

视图.py

def create_post_api_view(request):
    user = request.user
    post = Post(user=user)
    serializer = PostCreateSerializer(post, 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)

更新:

有效载荷。

Authorization: Token XXXX

: 
User-Agent: PostmanRuntime/7.26.2
Accept: */*
Postman-Token: 066c9a26-af76-4a44-9e9f-a3326050fa"
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=--------------------------554448102853056787089432
Content-Length: 123293

Request Body
title: "Another Trial api posts"
image: {…}
_events: {}
_eventsCount: 3
_readableState: {…}
autoDestroy: false
awaitDrain: 0
buffer: {…}
head: null
length: 0
tail: null
decoder: null
defaultEncoding: "utf8"
destroyed: true
emitClose: false
emittedReadable: false
encoding: null
endEmitted: true
ended: true
flowing: true
highWaterMark: 65536
length: 0
needReadable: false
objectMode: false
paused: false
pipes: null
pipesCount: 0
readableListening: false
reading: false
readingMore: false
resumeScheduled: false
sync: false
autoClose: true
bytesRead: 5473
closed: true
fd: null
flags: "r"
mode: 438
path: "C:\Users\danny\Desktop\test images\cat.jpg"
readable: false

postimage: [2]
0: {…}
_events: {}
_eventsCount: 3
_readableState: {…}
autoDestroy: false
awaitDrain: 0
buffer: {…}
decoder: null
defaultEncoding: "utf8"
destroyed: true
emitClose: false
emittedReadable: false
encoding: null
endEmitted: true
ended: true
flowing: true
highWaterMark: 65536
length: 0
needReadable: false
objectMode: false
paused: false
pipes: null
pipesCount: 0
readableListening: false
reading: false
readingMore: false
resumeScheduled: false
sync: false
autoClose: true
bytesRead: 7350
closed: true
fd: null
flags: "r"
mode: 438
path: "C:\Users\danny\Desktop\test images\041520_mt_supernova_feat-1028x579.jpg"
readable: false
1: {…}
_events: {}
_eventsCount: 3
_readableState: {…}
autoDestroy: false
awaitDrain: 0
buffer: {…}
decoder: null
defaultEncoding: "utf8"
destroyed: true
emitClose: false
emittedReadable: false
encoding: null
endEmitted: true
ended: true
flowing: true
highWaterMark: 65536
length: 0
needReadable: false
objectMode: false
paused: false
pipes: null
pipesCount: 0
readableListening: false
reading: false
readingMore: false
resumeScheduled: false
sync: false
autoClose: true
bytesRead: 109530
closed: true
fd: null
flags: "r"
mode: 438
path: "C:\Users\danny\Desktop\test images\Tischvase-X-Form-VX-silber-dek-Holst-Porzellan.jpg"
readable: false
Response Headers
Date: Mon, 27 Jul 2020 10:09:18 GMT
Server: WSGIServer/0.2 CPython/3.8.2
Content-Type: application/json
Vary: Accept, Accept-Language, Cookie
Allow: POST, OPTIONS
X-Frame-Options: SAMEORIGIN
Content-Length: 41
Content-Language: en

Response Body
{"postimage":["This field is required."]}

更新的创建序列化程序

class PostCreateSerializer(serializers.ModelSerializer):
images = serializers.ImageField()
class Meta:
    model = Post
    fields = ['id','title','image', 'images',]

def create(self,validated_data):
    user = self.context['request'].user
    title = validated_data['title']
    image = self.context['request'].FILES.get('image')
    images = self.context['request'].FILES.get('images')
    m1 = Post(
        title=title,
        image=image,
        user=user
    )
    m1.save()
    m2 = PostImage(
        post=m1,
        images=images
    )
    m2.save()
    validated_data['images']=m2.images
    return validated_data

基于上次编辑的响应

{
"title": "Another Trial api posts",
"image": null,
"images": "http://127.0.0.1:8000/media/posts/postimage/Tischvase-X-Form-VX-silber-dek-Holst-Porzellan.jpg"

}

现在另一个图像是空的..

谢谢

标签: djangodjango-modelsdjango-rest-frameworkdjango-forms

解决方案


我认为您应该为您的序列化程序编写自己的创建方法。像这样的东西

楷模

class MyModel(models.Model):
    field1 = models.CharField(max_length=50)
    def __str__(self):
        return str(self.field1)

class MyModel2(models.Model):
    field2 = models.CharField(max_length=50)
    image = models.ImageField(upload_to='images')
    foreignkeytomymodel = models.ForeignKey(MyModel,on_delete=models.CASCADE)

    def __str__(self):
        return str(self.field2)

序列化器

class MyModelSerializer(serializers.ModelSerializer):
    field2 = serializers.CharField(required=True)
    image = serializers.ImageField(required=True)
    class Meta:
        model = MyModel
        fields = ['field1','field2', 'image']

    def create(self,validated_data):
        field1 = validated_data['field1']
        field2 = validated_data['field2']
        image = self.context['request'].FILES.get('image')
        m1 = MyModel(
            field1=field1
        )
        m1.save()
        m2 = MyModel2(
            field2=field2,
            image=image,
            foreignkeytomymodel=m1
        )
        m2.save()
        validated_data['field2']=m2.field2
        validated_data['image']=m2.image
        return validated_data

意见

serializer = MyModelSerializer(data=request.data, context={'request':request})
if serializer.is_valid():
    serializer.save()
    return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)

根据您的序列化程序更新 -

class PostCreateSerializer(serializers.ModelSerializer):
    images = serializers.ImageField()
    class Meta:
        model = Post
        fields = ['id','title','image', 'images',]

    def create(self,validated_data):
        user = self.context['request'].user
        title = validated_data['title']
        image = self.context['request'].FILES.get('image')
        images = self.context['request'].FILES.get('images')
        m1 = Post(
            title=title,
            image=image,
            user=user
        )
        m1.save()
        m2 = PostImage(
            post=m1,
            images=images
        )
        m2.save()
        validated_data['image']=m1.image
        validated_data['images']=m2.images
        return validated_data

推荐阅读