Profileapp 시작 그리고 ModelForm
python manage.py startapp profileapp 명령어를 통해 profileapp을 만든다.
그리고 settings.py에 다음과 같이 profileapp을 추가해준다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrap4',
'accountapp',
'profileapp',
]
마찬가지로 urls.py에도 profileapp에 대한 정보를 추가해준다.
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accountapp.urls')),
path('profiles/', include('profileapp.urls')),
]
models.py에 모델을 만들어준다.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') # User가 탈퇴하면 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)
account는 django에서 기본적으로 제공해주는 form이 있었지만,
profile은 기본적으로 제공해주는 form이 없어 직접 만들어야한다.
새로운 form을 만들어서 사용하면된다, 직접 form을 만드는것 보다 기존의 model을 form으로 변환해주는 ModelForm이라는게 존재하는데 더 편하하므로 ModelForm을 사용하자.
forms.py를 만들어주고 ModelForm을 상속받아 어떤 Model을 사용하고 어떤 field를 사용하지 코드로 작성해주자.
class ProfileCreationForm(ModelForm):
class Meta:
model = Profile
fields = ['image', 'nickname', 'message']
profileapp 구현 시작
우선 model을 만들었으니 database에 적용시켜주는 작업이 필요하다.
다음과 같이 database에 적용시켜주자.
profileapp의 views.py에 createview를 만들어준다.
class ProfileCreateView(CreateView):
model = Profile
context_object_name = 'target_profile'
form_class = ProfileCreationForm
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'profileapp/create.html'
view를 만들었으면 url을 설정과 create.html을 만들어준다.
app_name = 'profileapp'
urlpatterns = [
path('create/', ProfileCreateView.as_view(), name='create')
]
{% extends 'base.html' %}
{% load bootstrap4 %}
{% block content %}
<div style="text-align: center; max-width: 500px; margin: 4rem auto">
<div class="mb-4">
<h4>Profile Create</h4>
</div>
<form action="{% url 'profileapp:create' %}" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
</form>
</div>
{% endblock %}
그리고 http://127.0.0.1:8000/profiles/create/에 접속하면
다음과 같은 화면이 나온다.
프로필을 설정할 수 있도록 해당 페이지로 이동할 수 있도록 해줘야 하므로
detail.html에서 만약 profile이 없다면 해당 페이지로 갈수 있는 링크를 띄워준다.
{% if target_user.profile %}
<h2 style="font-family:'NanumGothic'">
{{ target_user.profile.nickname }}
</h2>
{% else %}
<a href="{% url 'profileapp:create' %}">
<h2 style="font-family: NanumGothic">
Create Profile
</h2>
</a>
{% endif %}
만약 profile을 설정을 안했으면 위와 같이 Change Profile를 눌러 프로필을 설정할 수 있는 페이지로 이동이 가능하다.
하지만 이때 이미지파일을 등록하기 위해서는
<form action="{% url 'profileapp:create' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
</form>
form 태그에 enctype="multipart/form-data"를 추가해줘야 한다.
그러나 여전히 문제가 발생한다.
왜나하면 model에는 user라는 field가 있는데 form에서 user의 정보를 사용하지 않았기 때문이다 (즉, 다른 사람의 profile을 설정할 수 도 있기 때문이다.)
해당 부분은 서버 내에서 구현을 할것이다.
방법은 views.py의 ProfileCreateView에 form_valid를 추가해서 해결을 할 수 있다.
def form_valid(self, form):
temp_profile = form.save(commit=False) #날라온 form의 정보를 일시적으로 저장 (user 정보는 없음)
temp_profile.user = self.request.user #profile의 user를 request를 보낸 user로 설정
temp_profile.save() #해당 정보를 저장
return super().form_valid(form)
해당 코드를 추가해주면 다음과 같이 profile을 설정할 수 있게 된다.
'기타 > django' 카테고리의 다른 글
작정하고 장고 - get_success_url 함수 (0) | 2023.05.24 |
---|---|
작정하고 장고 - profile 마무리 (0) | 2023.05.24 |
작정하고 장고 - decorator, superuser, media (0) | 2023.05.17 |
작정하고 장고 - Authentication 인증시스템 구축 (0) | 2023.05.15 |
작정하고 장고 - UpdateView, DeleteView (0) | 2023.05.13 |
댓글