detail 페이지로 들어갔는데 사용자의 ID가 노출되는 문제
-> ID를 Nickname으로 바꿔주기
프로필 이미지(image), 닉네임(nickname), 상태메세지(message)
이 3가지를 같이 묶은 profileapp 을 만들 것이다.

account객체와 profile객체를 1대 1로 매칭을 시켜줄 것이다.
즉, 하나의 account객체에는 하나의 profile만 존재 가능

다음 세가지 구현

DeleteView와 DetailView는 구현하지 않을 것이다.
accountapp과 연결돼있고, 그 연결돼있는 account가 회원 탈퇴를 눌렀을 때 그때만 profile이 같이 사라지도록 할 것이다. (따로 delete를 할 수 있도록 설정 x)
detailView도 페이지를 꾸며줄 용도로만 사용할 것이기 때문에 굳이 profile만 따로 볼 수 있는 detail 페이지를 구현하진 않을 것이다.

# 새로운 app 인 profileapp 만들어주기
python manage.py startapp profileapp
pragmatic/profileapp이라는 새로운 app 생성됨

pragmatic/settings.py에 profileapp 추가
# pragmatic/pragmatic/settings.py
...
INSTALLED_APPS = [
...
'accountapp',
'profileapp' # profileapp 을 사용하겠다고 명시
]
pragmatic/urls.py에 profileapp 추가
# pragmatic/pragmatic/urls.py
...
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accountapp.urls')),
path('profiles/', include('profileapp.urls')),
# include -> profileapp.urls (지금은 없는) 로 하위 분기하도록 연결시켜줌
]
profileapp.urls로 하위 분기하도록 연결시켜줬기 때문에 profileapp에 urls.py파일 만들어주기
app_name 설정
그 내부에는 urlpattern에 대한 정보 기입
데이터를 담고자 하는, DB와 연동하기 위한 model 만들기
# pragmatic/profileapp/urls.py
app_name = 'profileapp'
urlpatterns = [
]
# pragmatic/pragmatic/models.py
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Profile(models.Model):
# Profile 과 user 를 하나씩 연결해준다.
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
image = models.ImageField(upload_to='profile/', null=True)
nickname = models.CharField(max_length=20, unique=True, null=True)
message = models.CharField(max_length=100, null=True)
OneToOneField(User, : 이 profile의 주인이 누구인지
우리가 사용하는 User 객체와 연결을 하고 : User
on_delete=models.CASCADE, → "user가 탈퇴하면 profile도 사라진다"
on_delete : 연결되어있는 User 객체가 delete될 때 그와 연결되어 있는 profile객체가 어떤 행동을 보일것인지를 담당하는 것
CASCADE : 객체가 사라질 때 이 profile도 없어지도록 설정
related_name='profile')
예를 들어 우리가 view에서 request.user 이런식으로 user 객체에 접근을 했었는데, 굳이 따로 profile 객체를 찾지 않더라도 request.user.profile 이런 식으로 해당 user 객체의 profile로 바로 연결할 수 있도록 이름을 설정
upload_to
이미지를 받아서 서버 내부에다가 이미지 파일을 저장할 것.
그런데 그 이미지가 어디에 저장 될 것인지에 대한 경로 설정
전에 설정했던 MEDIA_URL = '/media/' ,MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
이 /media/ 밑에 profile/ 이라는 경로가 추가되어 그 안에 이미지가 다 저장되는 것.
null=True
"꼭 프로필 사진을 올리지 않아도 괜찮다" 는 옵션
max_length : 최대 20자
unique=True : Profile 객체에서 이 nickname 은 하나가 유일해야함, 사람마다 고유한 닉네임을 가질 수 있도록 설정.
null=True : 닉네임이 설정되지 않았다면 설정해달라는 메세지를 띄우는 방식으로 구현
최대 100자, null=True
accountapp의 view에서 model뿐만 아니라 form_class를 지정해줬는데, 이 form을 만들어줘야 함.
하지만 이것을 일일이 다 만들어 줄 수는 없다.
1) Form
Account App에서 UserCreationForm은 장고에서 기본적으로 제공해주는 계정에 관련된 Form이었다.
하지만, Profile App은 장고에서 제공해주지 않기 때문에, 직접 만들어주어야 함.

form에서도 model과 비슷한 필드들이 다 있다.
비슷하게 다음과 같이 새로운 form을 만들어서 그 form을 사용해야 한다.
이 내용들이 수십 수백개가 된다면, 일일이 내용을 타입핑 하는 것이 어렵다 → ModelForm

기존에 있었던 모델을 form으로 그대로 변환해주는 기능
ModelForm을 상속받은 후에 어떤 모델을 사용하고, 어떤 필드를 입력할 수 있게 만들 것 인지 설정.
→ 그 모델이 그대로 form으로 변환됨.
1) forms.py 생성
# pragmatic/profileapp/forms.py
from django.forms import ModelForm
from profileapp.models import Profile
class ProfileCreationForm(ModelForm): #ModelForm 상속 받기
class Meta:
model = Profile
fields = ['image','nickname','message'] # 사용할 필드
# model 에서는 user 라는 필드가 하나 더 있긴 하지만
# user 는 서버에서 따로 처리를 할것
