Home > Back-end >  Django AWS S3 object storage boto3 media upload error
Django AWS S3 object storage boto3 media upload error

Time:01-04

I used django docker and aws s3 bucket for my project. I configure my settings file for my bucket and it is working but i got an error while uploading media files "expected string or bytes-like object" and docker log error if not VALID_BUCKET.search(bucket) and not VALID_S3_ARN.search(bucket). I used django forms and function based view.

models.py

def user_directory_path(instance, filename):
    tenant = connection.get_tenant()
    return 'profile_photos/{0}/{1}'.format(tenant, filename)

class UserProfilePhoto(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    profilephoto = models.ImageField(blank=True,default="profile_photos/profilephoto.png",upload_to=user_directory_path )

views.py

def userprofile(request,id):
    get_object_or_404(User,id = id)
    if request.user.userprofile.status == 3 or str(request.user.id) == str(id):
            now_today =  datetime.now(pytz.timezone('Europe/Istanbul'))
            announcements=Announcements.objects.filter(announce_type="announcement")
            current_page="Kullanıcı Profili" 
            user=User.objects.filter(id=id).first() 
            user_doc_create=InsuranceFile.objects.filter(file_creator=user.username)
            user_doc_create_last_month=InsuranceFile.objects.filter(file_creator=user.username, created_at__gte=now()-relativedelta(months=1)).count()
            ratio_of_doc = ratio_utils(user_doc_create_last_month,user_doc_create.count())   
            user_doc_update=InsuranceFile.objects.filter(file_updater=user.id)
            user_doc_update_last_month=InsuranceFile.objects.filter(file_updater=user.id, updated_at__gte=now()-relativedelta(months=1)).count()
            ratio_of_doc_update = ratio_utils(user_doc_update_last_month,user_doc_update.count())    
            path_check=str("/account/userprofile/"  id)
            profilephoto=UserProfilePhoto.objects.filter(user=request.user).first()
            previous_profilephoto=profilephoto.profilephoto
            form_user=CreateUserForm(request.POST or None , instance=request.user)
            form_userprofile=UserProfileForm(request.POST or None , instance=request.user.userprofile)
            form_userphoto=UserProfilePhotoForm(request.POST or None,request.FILES, instance=request.user.userprofilephoto,)
            is_confirmed=False
            if TOTPDevice.objects.filter(user_id=id).first():
                totp=TOTPDevice.objects.filter(user_id=id).first()
                is_confirmed=totp.confirmed
            if request.method == 'POST':
                if form_userphoto.is_valid() and form_userprofile.is_valid() and form_user.is_valid():
                    with transaction.atomic():
                        form_userprofile.save()
                        if str(request.FILES) != "<MultiValueDict: {}>":
    
                            upload_profile_photo(request,form_userphoto,user,previous_profilephoto)                             
                        messages.success(request,"Profil başarılı bir şekilde güncellendi.")
                        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
            return render(request,'userprofile.html',{"now_today":now_today,"ratio_of_doc_update":ratio_of_doc_update,"user_doc_update_last_month":user_doc_update_last_month,"user_doc_update":user_doc_update,"announcements":announcements,"current_page":current_page,"user_doc_create_last_month":user_doc_create_last_month,"ratio_of_doc":ratio_of_doc,"user_doc_create":user_doc_create,"path_check":path_check,"profilephoto":profilephoto,"is_confirmed":is_confirmed,"user":user,"form_userprofile":form_userprofile,"form_userphoto":form_userphoto,"form_user":form_user})
    messages.warning(request,"Bu işlemi yapmaya yetkiniz bulunmamaktadır.")
    return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

upload*_profile function*

import boto3
def upload_profile_photo(request,form_userphoto,user,previous_profilephoto):
    s3 = boto3.client('s3',
            aws_access_key_id="AKIAW7UXTA7VBPUVLPGW",
            aws_secret_access_key= "IScWHTd9aSn E9E9w1eiianT0mgoRG/j 1SdsMrJ")   
     
    if previous_profilephoto !=  "profile_photos/profilephoto.png":      
        s3.delete_object(Bucket='dj-crm-tenant', Key= f'media/{previous_profilephoto}')
    form_userphoto.save() 

settings.py

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_CUSTOM_DOMAIN = 'dj-crm-tenant.s3.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'}
AWS_DEFAULT_ACL = 'public-read'
AWS_LOCATION = 'static'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
DEFAULT_FILE_STORAGE = 'dj_crm_tenant.storages.MediaStore'

storages.py

from storages.backends.s3boto3 import S3Boto3Storage
class MediaStore(S3Boto3Storage):
    location = 'media'
    file_overwrite = False

when i try to change my user profilephoto i got an error.

i tried to upload file to my s3 bucket i got the previosuly mentioned error.

I am trying to upload media files to my s3 bucket using django-forms and boto

I followed https://github.com/veryacademy/YT-Django-Media-Static-AWS-S3 tutorial

CodePudding user response:

Problem seems to be about your .env file. You cannot connect to your bucket since your key and id is not read by the program.

You can also install dotenv package for managing your env files.

  • Related