Django REST: Uploading and serializing multiple images

后端 未结 2 927
离开以前
离开以前 2020-11-28 09:21

I have 2 models Task and TaskImage which is a collection of images belonging to Task object.

What I want is to be able to add

相关标签:
2条回答
  • 2020-11-28 09:57

    You have read_only set to true in TaskImageSerializer nested field. So there will be no validated_data there.

    0 讨论(0)
  • 2020-11-28 10:16

    Description for the issue

    The origin of the exception was a KeyError, because of this statement

    images_data = validated_data.pop('images')
    

    This is because the validated data has no key images. This means the images input doesn't validate the image inputs from postman.

    Django post request store InMemmoryUpload in request.FILES, so we use it for fetching files. also, you want multiple image upload at once. So, you have to use different image_names while your image upload (in postman).

    Change your serializer to like this:

    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
    

    I don't know about your view, but I'd like to use ModelViewSet preferrable view class

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

    Postman console:

    DRF result:

    {
            "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"
                }
            ]
        }
    

    UPDATE

    This is the answer for your comment.

    In django reverse foreignKey are capturing using _set. see this official doc. Here, Task and TaskImage are in OneToMany relationship, so if you have one Task instance, you could get all related TaskImage instance by this reverse look-up feature.

    Here is the example:

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

    Here this task_img_set_all will be equal to TaskImage.objects.filter(task_id=1)

    0 讨论(0)
提交回复
热议问题