해결된 질문
작성
·
355
·
수정됨
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가 발생하는 것입니다.
화이팅입니다. :-)
단순히 해결 방법 뿐만 아니라, 근본적인 것 까지 알려주셔서 너무너무 감사드립니다..... ㅠㅠㅠ