🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

  • 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    해결됨

AttributeError at /accounts/profile/edit/ 질문입니다!

23.01.18 17:56 작성 23.01.18 17:59 수정 조회수 276

1

안녕하세요 강사님!

사용자 프로필 페이지 및 프로필 수정

관련하여 강의듣고 있구요

12분쯔음에 localhost:8000/accounts/profile/edit/

부분 관련하여 페이지 접속하고, 수정하는 과정 진행중인데요.

AttributeError at /accounts/profile/edit/
'User' object has no attribute 'profile'

이런 에러가 뜨네요 ㅠㅠ

Traceback에 보면


/Users/daniel_choi/Desktop/total_projects/new_instagram/accounts/views.py, line 39, in profile_edit
# FBV
@login_required
def profile_edit(request):
    try:
        # 현재 이 코드는 Profile.objects.get(user=request.user)와 같은 의미다.
        profile = request.user.profile …
    except Profile.DoesNotExist:
        profile = None
    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():

이렇게 나오구요.

바로 위의 코드중에서

        profile = request.user.profile 

이부분이 문제가 되는것 같습니다.

강의를 다시들으면서 체크해봐도 무엇이 잘못되었는지 잘 못찾겠어서 문의드립니다!! ㅠㅠㅠ

 


혹시 몰라서 추가로 제가 작성한 코드 중에서

중요하겠다 싶은 부분도 함께 첨부하겠습니다!

#forms.py

from django import forms
from .models import Profile


class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['address', 'zipcode']
#models.py

from django.conf import settings
from django.db import models

# Create your models here.


class Profile(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    address = models.CharField(max_length=100)
    zipcode = models.CharField(max_length=6)  # validators = []
#views.py

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView, UpdateView

from .forms import ProfileForm
from .models import Profile
# Create your views here.

# FBV 방식
# @login_required
# def profile(request):
#     return render(request, 'accounts/profile.html')

# CBV 방식


class ProfileView(LoginRequiredMixin, TemplateView):
    template_name = 'accounts/profile.html'


profile = ProfileView.as_view()

# CBV
# class ProfileUpdateView(LoginRequiredMixin, UpdateView):
#     model = Profile
#     form_class = ProfileForm


# profile_edit = ProfileUpdateView.as_view()


# FBV
@login_required
def profile_edit(request):

    try:
        # 현재 이 코드는 Profile.objects.get(user=request.user)와 같은 의미다.
        profile = request.user.profile
    except Profile.DoesNotExist:
        profile = None

    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            profile = form.save(commit=False)
            profile.user = request.user
            profile.save()
            return redirect('profile')
    else:
        form = ProfileForm(instance=profile)
    return render(request, 'accounts/profile_form.html', {
        'form': form
    })

 

답변 1

답변을 작성해보세요.

1

안녕하세요.

결론부터 말씀드리자면, Profile 모델에서 User 모델에 대한 외래키를 models.OneToOneField(1:1 관계)가 아니라, models.ForeignKey (1:N 관계) 로 잡으셨기 때문입니다.

models.OneToOneField로 관계를 지정한 것은
하나의 User 모델 인스턴스는 단 하나의 Profile 모델 인스턴스 만을 가지도록 설계했기 때문입니다.

Profile 모델 측에 User 모델과 1:1 관계로 설정하면,
User 인스턴스에서는 .profile 속성이 자동으로 부여됩니다. Profile 모델명을 소문자로 변경한 이름입니다.
그럼 user.profile 로 접근하면, Profile.objects.get(user=user) 를 수행한 것과 동일한 동작을 합니다. user 인스턴스 입장에서 관련 Profile 을 조회할 때 훨씬 편리하고 간결하게 조회할 수 있죠.

그런데, models.ForeignKey로 설정하시게 되면
디폴트로 User 인스턴스에 .profile_set 속성이 자동으로 부여됩니다.
이때에는 .profile_set 속성이 있을 뿐 .profile 속성은 없는 거죠. 그래서 말씀하신 AttributeError가 발생하는 것입니다.

화이팅입니다. :-)

단순히 해결 방법 뿐만 아니라, 근본적인 것 까지 알려주셔서 너무너무 감사드립니다..... ㅠㅠㅠ

채널톡 아이콘