简体   繁体   中英

How to return an array of images through HttpResponse in Django?

Suppose I had a Dog Object and it had fields like name, weight, and breed. Serializing these and returning them was easy as they were strings. I then added a field called image_url, which was the s3 path (I am storing their images in my s3 bucket). In my DogView (which returns all the dogs a user owns), I would have something like this:

class DogsView(ListAPIView):
    def get(self, request):
        user = request.user
        dogs = Dog.objects.filter(user=user)
        dog_serializer = DogSerializer(dogs, many=True)
        s3 = boto3.resource("s3")
        for dog in dog_serializer.data:
            if len(dog["image_url"]) > 0:
                s3_object = s3.Object('my-dog-photos', dog["image_url"])
                file_stream = io.StringIO()
                s3_object.download_fileobj(file_stream)
                img = img.imread(file_stream)
                dog["image"] = img

        return Response(product_serializer.data)

However, when I do this, I get

TypeError: string argument expected, got 'bytes'

How would I be able to append my bytes/file to my serializer.data (or just return an array of images via HttpResponse)?

DRF Response class expects a json serializable input so if you really have to pass bytes data in Response, you can just convert it to string by changing this line:

dog["image"] = str(img)

You will still have to convert it back to bytes on your client application.

However, this is NOT how json should ever be used. You should just pass urls of your images and let client application handle the downloads. Here is a simple setup for s3 media and static file storage for django. This way serializer will return direct links to s3 bucket and you can also upload your files directly to s3 with django admin (if you're using it).

in your_project/settings.py

AWS_STORAGE_BUCKET_NAME = 'your bucket name'
AWS_S3_REGION_NAME = 'us-east-1'
AWS_ACCESS_KEY_ID = 'access_key_id'
AWS_SECRET_ACCESS_KEY = 'secret_access_key'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'your_project.custom_storages.StaticStorage'

DEFAULT_FILE_STORAGE = 'your_project.custom_storages.MediaStorage'
MEDIAFILES_LOCATION = 'media'
MEDIA_ROOT = '/%s/' % MEDIAFILES_LOCATION
MEDIA_URL = '//%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)

create your_project/custom_storages.py

from storages.backends.s3boto3 import S3Boto3Storage


class StaticStorage(S3Boto3Storage):
    location = 'static'


class MediaStorage(S3Boto3Storage):
    location = 'media'

you will need django-storages and boto3 libraries

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM