我有两个模型Task
和TaskImage
这是属于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请求时:
我得到了以下回溯:
文件
“/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.FILES
Preferable View类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中,使用
serializer
捕获。请参见。这里,ModelViewSet
和reverse 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/