当前位置: 首页 > 知识库问答 >
问题:

Django REST:上传和序列化多个图像

冀弘济
2023-03-14

我有两个模型TaskTaskImage,这是属于Task对象的图像集合。

我想要的是能够向我的任务对象添加多个图像,但我只能使用两个模型。目前,当我添加图像时,它不允许我上传图像和保存新对象。

设置。派克

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

序列化程序。派克

class TaskImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskImage
        fields = ('image',)


class TaskSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.ReadOnlyField(source='user.username')
    images = TaskImageSerializer(source='image_set', many=True, read_only=True)

    class Meta:
        model = Task
        fields = '__all__'

    def create(self, validated_data):
        images_data = validated_data.pop('images')
        task = Task.objects.create(**validated_data)
        for image_data in images_data:
            TaskImage.objects.create(task=task, **image_data)
        return task

模型。派克

class Task(models.Model):
    title = models.CharField(max_length=100, blank=False)
    user = models.ForeignKey(User)

    def save(self, *args, **kwargs):
        super(Task, self).save(*args, **kwargs)

class TaskImage(models.Model):
    task = models.ForeignKey(Task, on_delete=models.CASCADE)
    image = models.FileField(blank=True)

但是,当我发出post请求时:

我得到以下回溯:

文件“/Applications/Anaconda/Anaconda/envs/godo/lib/python3.6/site packages/django/core/handlers/exception.py”。响应=获取响应(请求)

文件“/Applications/Anaconda/Anaconda/envs/godo/lib/python3.6/site-packages/django/core/handlers/base.py”在_get_-response 187中。回应=自我。通过中间件处理异常(e,请求)

文件"/应用程序/anaconda/anaconda/envs/godo/lib/python3.6/site-包/django/core/处理程序/base.py"在_get_response185。

文件"/应用程序/anaconda/anaconda/envs/godo/lib/python3.6/site-包/django/视图/装饰器/csrf.py"在wrapped_view58。返回view_func(*args,**kwargs)

视图95中的文件“/Applications/Anaconda/Anaconda/envs/godo/lib/python3.6/site packages/rest_framework/viewsets.py”。回归自我。调度(请求,*args,**kwargs)

在调度494中的file"/应用程序/anaconda/anaconda/envs/godo/lib/python3.6/site包/rest_framework/views.py"

handle_exception454中的file"/应用程序/anaconda/anaconda/envs/godo/lib/python3.6/site-包/rest_framework/views.py"。self.raise_uncaught_exception(exc)

文件“/Applications/Anaconda/Anaconda/envs/godo/lib/python3.6/site packages/rest_framework/views.py”,位于dispatch 491中。响应=处理程序(请求、*args、**kwargs)

create 21中的文件“/Applications/Anaconda/Anaconda/envs/godo/lib/python3.6/site packages/rest\u framework/mixins.py”。自己执行创建(序列化程序)

执行创建152中的文件“/Users/gr/Desktop/PycharmProjects/godo/api/views.py”。序列化程序。保存(用户=self.request.user)

保存214中的文件“/Applications/Anaconda/Anaconda/envs/godo/lib/python3.6/site packages/rest_framework/serializers.py”。自己实例=自我。创建(已验证的数据)

create 67中的文件“/Users/gr/Desktop/PycharmProjects/godo/api/serializers.py”。图像\数据=已验证\数据。弹出(“图像”)

异常类型:在/api/tasks/Exception值处出现KeyError:'images'

共有2个答案

公孙智
2023-03-14

TaskImageSerializer嵌套字段中将read\u设置为true。因此,那里将没有经过验证的数据。

姬宝
2023-03-14

问题说明

异常的起源是一个KeyError,因为这个语句

images_data = validated_data.pop('images')

这是因为经过验证的数据没有键图像。这意味着图像输入不验证来自邮递员的图像输入。

Django后请求存储InMemmoryUpload请求。文件,所以我们用它来获取文件。此外,你想一次上传多个图像。因此,您必须使用不同的image_names,而您的图像上传(在邮递员)。

将您的序列化程序更改为如下所示:

class TaskSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.ReadOnlyField(source='user.username')
    images = TaskImageSerializer(source='taskimage_set', many=True, read_only=True)

    class Meta:
        model = Task
        fields = ('id', 'title', 'user', 'images')

    def create(self, validated_data):
        images_data = self.context.get('view').request.FILES
        task = Task.objects.create(title=validated_data.get('title', 'no-title'),
                                   user_id=1)
        for image_data in images_data.values():
            TaskImage.objects.create(task=task, image=image_data)
        return task

我不知道您的视图,但我想使用ModelViewSetpreferrable视图类

class Upload(ModelViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()

邮递员控制台:

DRF结果:

{
        "id": 12,
        "title": "This Is Task Title",
        "user": "admin",
        "images": [
            {
                "image": "http://127.0.0.1:8000/media/Screenshot_from_2017-12-20_07-18-43_tNIbUXV.png"
            },
            {
                "image": "http://127.0.0.1:8000/media/game-of-thrones-season-valar-morghulis-wallpaper-1366x768_3bkMk78.jpg"
            },
            {
                "image": "http://127.0.0.1:8000/media/IMG_212433_lZ2Mijj.jpg"
            }
        ]
    }

使现代化

这是你评论的答案。

在django中,使用\u set捕获反向外键。看这个官方文件。在这里,TaskTaskImage处于OneToMany关系中,因此如果您有一个Task实例,您可以通过此反向查找功能获得所有相关的TaskImage实例。

以下是一个例子:

task_instance = Task.objects.get(id=1)
task_img_set_all = task_instance.taskimage_set.all()

这里这个task_img_set_all将等于TaskImage.objects.filter(task_id=1)

 类似资料:
  • 意见: URL: POST和GET在 中工作得很好我以前问过类似的问题,我肯定,问题是在前面,用AngularJS,我也是第一次使用AngularJS。但我现在想,可能是我的服务器应用程序出现了问题。 角代码: GET控制器工作良好,我累犯了我所有的图像: 对于文件上传,我使用了本指南 ,这里是指南中的代码: html代码:

  • 问题内容: 使用AJAX上传多张图片时遇到很多问题。我写这段代码: 的HTML jQuery / AJAX 我尝试了各种版本,但从未成功通过ajax发送多个数据。我已经按照这种方式尝试了以上所见,现在我仅获得POST信息。我知道为什么会收到POST,但我需要发送FILES信息,而且我不知道我哪里写错了。 我不是第一次使用Ajax,经常在大多数项目中使用它,但是我从未使用过发送多个文件,这现在困扰着

  • 我正在寻找一种方法来上传多个图像的描述。用户将从摄像头上传1-10张相当大的图片,所以最好在上传前调整图片大小。 要求: 浏览器兼容(包括手机浏览器和IE),可以依靠JavaScript(jQuery) 多个文件作为本机文件管理器中多个文件的选择,或者至少必须单击某个按钮来输入另一个文件 给每个文件添加一个描述 上传前调整文件大小(不需要与浏览器兼容) 上传提交 保留EXIF信息或至少提取GPS坐

  • 一旦用户点击掩码映像,我们就允许用户上传自定义映像,如果只有一个掩码映像:https://codepen.io/kidsdial/pen/jjbvon就可以正常工作 要求: 但是如果有多个掩码映像,那么用户也应该能够上传所有掩码映像上的自定义映像[类似https://codepen.io/kidsdial/pen/rrmypr],但是现在它只适用于单个映像.... 2图像代码页:https://c

  • 一旦用户点击掩码映像,我们就允许用户上传自定义映像,如果只有一个掩码映像:https://codepen.io/kidsdial/pen/jjbvon就可以正常工作 要求: 但是如果有多个掩码映像,那么用户也应该能够上传所有掩码映像上的自定义映像[类似https://codepen.io/kidsdial/pen/rrmypr],但是现在它只适用于单个映像.... 2图像代码页:https://c

  • 本文向大家介绍PHP实现多图上传和单图上传功能,包括了PHP实现多图上传和单图上传功能的使用技巧和注意事项,需要的朋友参考一下 下面一段代码给大家介绍php实现单图上传和多图上传的功能,具体代码如下所示: 总结 以上所述是小编给大家介绍的PHP实现多图上传和单图上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对呐喊教程网站的支持!