장고

개발 일지 27 - 프로필 이미지 추가 2

sorecord 2024. 9. 10. 09:15

어제는 프로필 화면 구현과 setting.py와 url.py로 이미지에 연결할 경로까지 만들어 주었다.

 

오늘은 들어온 이미지를 view.py에 보내는 순간이다. 

 

def upload_profile_pic(request):
    user_id = request.session.get('user_id')
    print(f"User ID from session: {user_id}") 
    if request.method == 'POST' and request.FILES['profile_pic']:
        profile_pic = request.FILES['profile_pic']
        fs = FileSystemStorage()
        filename = fs.save(profile_pic.name, profile_pic)
        uploaded_file_url = fs.url(filename)
        
        try:
            # 사용자 ID로 UserProfile 가져오기
            user_profile,created = UserProfile.objects.get_or_create(user_id=user_id)
            user_profile.profile_image = uploaded_file_url  # 이미지 URL 저장
            user_profile.save()  # 변경사항 저장
        except UserProfile.DoesNotExist:
            print(f"No UserProfile found for user ID: {user_id}")  # 로그 출력
            # 사용자 프로필이 없는 경우에 대한 처리 추가
            return redirect('index')  # 적절한 리다이렉션
        return redirect('index')  # 적절한 리다이렉션 URL로 변경하세요.

    return redirect('index')  # GET 요청 시에도 리다이렉트  # 적절한 템플릿으로 변경하세요.

 

난 user_id를 세션을 통해서 가져왔다. 내가 좀 특이 케이스이다. 원래는 request.user를 사용해야 하는데 난 자꾸 admin이라고 뜨고 해결을 하지 못해서 세션을 사용한다. 이 부분에 대한 수정은 최대한 빨리 해 볼 예정이다. 

 

request.FILES는 Django에서 사용자가 업로드한 파일에 접근할 수 있는 딕셔너리다. 여기서 폼에서 전송된 파일을 받는다 .

fileSystemStorage()는 기본적으로 MEDIA_ROOT에 파일을 저장합니다. 

 

fs.save(name,content)는 name에 사용자가 업로드한 파일의 원래 이름을 사용한다.

content는 실제 파일 데이터이다. 

*만약 같은 파일의 이름이 있다면 장고에선 파일이름에 숫자를 추가하여 중복을 피한다. 

 

fs.url은 저장된 파일의 URL을 생성한다. 이 URL은 일반적으로 MEDIA_URL과 결합되어 사용된다. 

 


뒤에 코드를 설명하기 전에 유저의 프로필의 이미지 경로를 저장하는 모델이 필요하다. 

 

class UserProfile(models.Model):
    user = models.OneToOneField(User_information, on_delete=models.CASCADE)  # 사용자와 1:1 관계 설정
    profile_image = models.ImageField(upload_to='profile_images/', blank=True, null=True)  # 프로필 이미지 필드

    def __str__(self):
        return self.user.username

 

오직 한 유저에 한 프로필을 가질 수 있게 onetooneField를 사용한다.

 


이제 다시 코드로 돌아가서 ,

 

UserProfile.objects.get_or_create(user_id=user_id) => 주어진 조건에 맞는 객체를 찾고, 만약 해당 객체가 없으면 새로 생성하는 메서드이다. user_id의 형태는 문자열하고 숫자값이 아니라 원래는 request.user의 값이 들어가는 곳이다.

 

이 부분을 해결하기 위해서

request.session['user_id'] = user.id # 숫자값 받기

           

로그인을 성공했을때의 아이디를 받는 세션을 만들어서 받았다. 

 

user_profile.profile_image = uploaded_file_url => user_profile 객체의 profile_image 필드에 업로드된 이미지의 URL을 저장한다.

 

user_profile.save() =>save() 메서드는 객체의 현재 상태를 데이터베이스에 저장한다. user_profile profile_image 필드가 업데이트된 후 그 변경 사항을 데이터베이스에 반영한다.

 

이렇게 프로필 이미지 추가가 마무리 되었으면 좋겠지만 몇가지 문제가 더 남아있었다..