我有两个模型TaskTaskImage这是属于Task对象的图像集合。
我想要的是能够将多个图像添加到我的Task对象中,但我只能使用两个模型。目前,当我添加图像时,它不允许我上传和保存新对象。
设置.py

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

序列化程序.py
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

型号.py
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请求时:
python - Django REST:上传和序列化多个图像-LMLPHP
我得到了以下回溯:
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/django/core/handlers/exception.py”
在内部
41.响应=获取响应(请求)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/站点包/django/core/handlers/base.py”
在“获取”响应中
187年。response=self.process_exception_by_中间件(e,请求)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/站点包/django/core/handlers/base.py”
在“获取”响应中
185.response=wrapped_callback(请求,*回调参数,**回调参数)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/站点包/django/views/decorators/csrf.py”
在包裹视图中
58岁。返回视图_Func(*args,**kwargs)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/rest_framework/viewsets.py”
在视图中
95岁。返回self.dispatch(请求,*args,*kwargs)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/rest_framework/views.py”
正在调度中
494年。响应=self.handle_异常(exc)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/rest_framework/views.py”
在句柄中\异常
454年。self.raise_uncaught_exception(exc)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/rest_framework/views.py”
正在调度中
491年。响应=处理程序(请求、*args、*kwargs)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/rest_framework/mixins.py”
在创建中
21.self.执行创建(序列化程序)
中的文件“/users/gr/desktop/pycharmprojects/godo/api/views.py”
执行创建
152。serializer.save(user=self.request.user)
文件
“/applications/anaconda/anaconda/envs/godo/lib/python3.6/site packages/rest_framework/serializer.py”
在保存中
214.self.instance=self.create(已验证的数据)
中的文件“/users/gr/desktop/pycharmprojects/godo/api/serializer.py”
创造
67岁。images_data=validated_data.pop('images')
异常类型:keyError位于/api/tasks/exception value:'images'

最佳答案

问题描述
由于此语句,异常的来源是一个KeyError。这是因为经过验证的数据没有关键字。这意味着图像输入不会验证来自邮递员的图像输入。
django post request storeimages_data = validated_data.pop('images')inimages,因此我们使用它来获取文件。另外,您希望一次上载多个图像。所以,在上传图片时,你必须使用不同的图片名(邮差)。
把你的InMemmoryUpload改成这样,

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

我不知道您的视图,但我想使用request.FILESPreferable View类
class Upload(ModelViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()

邮差控制台
python - Django REST:上传和序列化多个图像-LMLPHP
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中,使用serializer捕获。请参见。这里,ModelViewSetreverse foreignKey是在_set关系中的,所以如果你有一个Task实例,你可以通过这个功能得到所有相关的TaskImage实例。
下面是例子
task_instance = Task.objects.get(id=1)
task_img_set_all = task_instance.taskimage_set.all()

这里,OneToMany等于Task

关于python - Django REST:上传和序列化多个图像,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48756249/

10-12 00:32
查看更多