Django + S3 не работает при обновлении профиля
Я работаю над веб-приложением django, раньше я не работал с S3, но как только я начал использовать его, я могу просматривать css js и все статические изображения, которые находятся там, а также стандартную картинку профиля пользователей,
Теперь проблема в том, что пользователи не могут загружать свои фотографии профиля, после того как они нажимают обновить и страница обновляется, их фотография профиля возвращается к стандартной и я теряю всю информацию, которая должна быть обновлена для профиля. это модель профиля:
class Profile(models.Model):
gender = (
('Female', 'Female',),
('Male', 'Male',),
)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
first_name = models.CharField(max_length=200,blank=True)
last_name = models.CharField(max_length=200,blank=True)
username = models.CharField(max_length=200)
email = models.EmailField(max_length=200)
birthdate = models.DateField(verbose_name=("birthdate"), null=True,blank=True)
gender = models.CharField(max_length=60, blank=True, default='',choices=gender,verbose_name="gender")
image = models.ImageField(upload_to='static/images/profile_pics/',default='static/images/profile_pics/profile.png',null=True, blank=True)
conception = models.ManyToManyField(Conception,related_name="profileconceptions")
bio = models.CharField(max_length=100, blank=True,default='')
slug = models.SlugField(null=True, blank=True,allow_unicode=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
phoneNumber = PhoneNumberField(null=True, blank=False, unique=True)
objects = ProfileManager()
def __str__(self):
#return f"{self.user.username}-{self.created.strftime('%d-%m-%Y')}"
return f'{self.user.username},{self.id}'
__initial_first_name = None
__initial_last_name = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__initial_first_name = self.first_name
self.__initial_last_name = self.last_name
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
SIZE = 300, 300
if self.image:
pic = Image.open(self.image.name)
pic.thumbnail(SIZE,Image.LANCZOS)
pic.save(self.image.name)
if self.slug == None:
slug = slugify(self.user.username,allow_unicode=True)
has_slug = Profile.objects.filter(slug=slug).exists()
count = 1
while has_slug:
count += 1
slug = slugify(self.user.username) + '-' + str(count)
has_slug = Profile.objects.filter(slug=slug).exists()
self.slug = slug
и это моя форма обновления для Profile forms.py
class ProfileUpdateForm(forms.ModelForm):
conception = forms.ModelMultipleChoiceField(queryset=Conception.objects, widget=forms.CheckboxSelectMultiple(), required=False)
class Meta:
model = Profile
fields = ['image','gender','birthdate','conception','bio','phoneNumber']
У меня есть еще одна форма для пользователя, которая содержит email пароль и имя пользователя, вот мой settings.py
# AWS S3 SETTINGS
AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = config("AWS_STORAGE_BUCKET_NAME")
AWS_URL=f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_DEFAULT_ACL = 'public-read'
AWS_S3_REGION_NAME = 'us-east-2'
AWS_S3_FILE_OVERWRITE = False
AWS_S3_OBJECT_PARAMETERS = {'CacheControl':'max-age=86400'}
#static
STATIC_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/static/'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIAFILES_LOCATION = 'static/images'
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/images/'
#DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
DEFAULT_FILE_STORAGE = 'myproject.custom_storage.PublicMediaStorage'
в моем custom_storage я поместил :
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class PublicMediaStorage(S3Boto3Storage):
location = 'static/images'
default_acl = 'public-read'
file_overwrite = False
за просмотры этой страницы :
def accountSettings(request):
#if request.method == 'POST':
if request.POST.get('submit') == 'Update':
u_form = UserUpdateForm(request.POST,instance=request.user)
p_form = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('accountSettings')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
context={
'u_form':u_form,
'p_form':p_form,
}
return render(request, 'user/settings.html', context)
для шаблона я использую форму enctype="multipart/form-data" <input class="btn"type="submit" name="submit" value="Update">
в чем проблема, раньше все работало без S3, но мне приходится его использовать.