如何使用DJango Rest Framework上传多张图片?

时间:2018-10-20 06:59:40

标签: django django-rest-framework image-uploading

我可以使用以下代码上传单个图像。如果我选择了多张图像,则只会上传所选图像中的最后一张图像。

models.py

class Image(models.Model):
property_id = models.ForeignKey(
                'properties.Address',
                null=False,
                default=1,
                on_delete=models.CASCADE
            )
image = models.ImageField(upload_to=directory_path)

serializers.py

class ImageSerializer(serializers.ModelSerializer):
class Meta:
    model = Image
    fields = (
        'property_id',
        'image'
    )

views.py

class ImageView(APIView):
parser_classes = (MultiPartParser, FormParser)

def get(self, request):
    all_images = Image.objects.all()
    serializer = ImageSerializer(all_images, many=True)
    return JsonResponse(serializer.data, safe=False)

def post(self, request, *args, **kwargs):
    file_serializer = ImageSerializer(data=request.data)
    if file_serializer.is_valid():
        file_serializer.save()
        return Response(file_serializer.data, status=status.HTTP_201_CREATED)
    else:
        return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)


我对Django有点陌生。我想遍历请求中收到的图像数组。data谁能告诉我该怎么做?

4 个答案:

答案 0 :(得分:2)

因此,我终于找到了一种以自己的方式解决问题的方法,因为我找不到以DRF方式进行操作的任何方法。我希望这个答案对Django社区有所帮助。我保持模型和序列化器相同,更改视图以遍历每个图像并使用序列化器保存。

views.py

class ImageView(APIView):
parser_classes = (MultiPartParser, FormParser)

def get(self, request):
    all_images = Image.objects.all()
    serializer = ImageSerializer(all_images, many=True)
    return JsonResponse(serializer.data, safe=False)

def post(self, request, *args, **kwargs):
    property_id = request.data['property_id']

    # converts querydict to original dict
    images = dict((request.data).lists())['image']
    flag = 1
    arr = []
    for img_name in images:
        modified_data = modify_input_for_multiple_files(property_id,
                                                        img_name)
        file_serializer = ImageSerializer(data=modified_data)
        if file_serializer.is_valid():
            file_serializer.save()
            arr.append(file_serializer.data)
        else:
            flag = 0

    if flag == 1:
        return Response(arr, status=status.HTTP_201_CREATED)
    else:
        return Response(arr, status=status.HTTP_400_BAD_REQUEST)

helpers.py

def modify_input_for_multiple_files(property_id, image):
dict = {}
dict['property_id'] = property_id
dict['image'] = image
return dict

models.py

class Image(models.Model):
property_id = models.ForeignKey(
                'properties.Address',
                null=False,
                default=1,
                on_delete=models.CASCADE
            )
image = models.ImageField(upload_to=directory_path)

serializers.py

class ImageSerializer(serializers.ModelSerializer):
class Meta:
    model = Image
    fields = (
        'property_id',
        'image'
    )

请求以querydict的形式出现。第images = dict((request.data).lists())['image']行将查询字典转换为python字典,然后在'image'键下遍历数组。

邮递员要求如下

enter image description here Posts images to the media folder of file system

答案 1 :(得分:1)

输出

{
    "id": 11,
    "product_number": "1005",
    "product_name": "Simple Wallpaper",
    "catalogue": 1,
    "product_images": [
        {
            "id": 6,
            "product_image_id": "11",
            "product_image_name": "Simple Wallpaper",
            "product_image_url": "http://127.0.0.1:8000/media/media/product_images/wall_HzUqs46.jpg",
            "product_item": 11
        },
        {
            "id": 7,
            "product_image_id": "12",
            "product_image_name": "Simple Walpaper 2",
            "product_image_url": "http://127.0.0.1:8000/media/media/product_images/wall_ywBmMmI.jpg",
            "product_item": 11
        }
    ]
}

在表单数据中使用以下数据作为邮递员的输入

键 - 值

product_number - 1005
product_name - Simple Wallpaper
catalogue - 1
product_images[0]product_image_id - 11
product_images[0]product_image_name - Simple Wallpaper
product_images[0]product_item - 3
product_images[0]product_image_url - File
product_images[1]product_image_id - 12
product_images[1]product_image_name - Simple Walpaper 2
product_images[1]product_item - 3
product_images[1]product_image_url - File

模型.py

class ProductItem(models.Model):
    product_number = models.CharField(null=False, unique=True, max_length=10)
    product_name = models.CharField(max_length=50, null=False)
    catalogue = models.ForeignKey(Catalogue, null=True, on_delete=models.SET_NULL)
class ProductImage(models.Model):
    product_image_id = models.CharField(max_length=20, null=False)
    product_image_name = models.CharField(max_length=20, null=False)
    product_image_url = models.ImageField(upload_to='media/product_images/',null=True)
    product_item = models.ForeignKey(ProductItem,on_delete=models.CASCADE, related_name="product_images")

Serializers.py

class ProductItemSerializer(serializers.ModelSerializer):
    product_images = ProductImageSerializer(many=True)

    class Meta:
        model = ProductItem
        fields = ["id","product_number","product_name","catalogue","product_images"]

    def create(self,validated_data):
        print("Validated data--",validated_data)
        product_image_data = validated_data['product_images']
        del validated_data['product_images']

        product_item_obj = ProductItem.objects.create(**validated_data)

        for product_image in product_image_data:
            image_obj = ProductImage.objects.create(product_item = product_item_obj, **product_image)

视图.py

class ProductItemView(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,UserUpdatePermission)
    authentication_classes = (TokenAuthentication,)
    serializer_class = ProductItemSerializer
    filter_backends = [filters.SearchFilter]
    search_fields = ['product_number']
    queryset = ProductItem.objects.all()

答案 2 :(得分:0)

您应该使用ListCreateAPIView的解决方案。您不必实现自己的视图并处理所有事情。

class ImageView(generics.ListCreateAPIView):
    parser_classes = (MultiPartParser, FormParser)
    queryset = Image.objects.all()
    serializer_class = ImageSerializer

    def get_serializer(self, *args, **kwargs):
        if isinstance(kwargs.get('data', {}), list):
            kwargs['many'] = True
        return super(CreateListModelMixin, self).get_serializer(*args, **kwargs)

答案 3 :(得分:0)

models.py

class Image(models.Model):
    property_id = models.ForeignKey(
                'properties.Address',
                null=False,
                default=1,
                on_delete=models.CASCADE
            )
    image = models.ImageField(upload_to=directory_path)

serializers.py

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = (
            'property_id',
            'image'
        )

views.py

class ImageAPIView(ListCreateAPIView):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    def post(self, request, *args, **kwargs):
        property_id = request.data['property']
        form_data = {}
        form_data['property']= property_id
        success = True
        response = []
        for images in request.FILES.getlist('images'):
            form_data['images']=images
            print(form_data)
            serializer = PropertyImageSerializers(data=form_data)
            if serializer.is_valid():
                serializer.save()
                response.append(serializer.data)
            else:
                success = False
        if success:
            #return Response(response, status=status.HTTP_201_CREATED)
           
            return Response({
            'status' : 1, 
            'message' : 'Success',
            'Data' : response,
            })
            
          #returnResponse(response,status=status.HTTP_400_BAD_REQUEST)

        return Response({
            'status' : 0, 
            'message' : 'Error!',
        })