[django] Profileapp Closure

Hyeseong·2020년 12월 15일
0

django

목록 보기
11/35

목표

: profileapp을 종결 시킬게요. 🤗

  • view 작성
  • template 작성
  • url
  • decorator

view

기존 ProfileCreateView 상속하면 되요! 하지만!!!! 그대로 복붙하면 되는 문제점이 있다는거

  • 하나, 그건 상속 받을 제네릭뷰를 변경해줘야 한다는거!😜
  • 둘, template_name의 문자열 값도 profileapp/update.html으로 반드시 바꿔줘야해요.😉
class ProfileUpdateView(UpdateView): # 테이블에 이미 있는 레코드를 수정하는 제네릭뷰를 상속 받아요.
    model = Profile
    context_object_name = 'target_profile'
    form_class = ProfileCreationForm
    success_url = reverse_lazy('accountapp:hello_world')
    template_name = 'profileapp/update.html'

template

profileapp에서 update.html을 만들게요.
이 화면은 회원가입과 같은 느낌인 수정화면이라는점! 내 프로필을 수정할 이미지, 닉네임, 메시지 form들이 나타나게 되요.

template_name을 지정해줬으니 해당 경로에 html파일이 있어야겠조?😒
기존 create.html을 그대로 복붙하되! 꼼꼼하게 달라지는 부분이 있으니 확인하고 넘어가야해요.(●'◡'●)

특히 form태그 부분을 주의 깊게 보셔야 합니다.
pk=target_profile.pk로 추가해 줘야한다는거~~😎

{% extends 'base.html' %}
{% load bootstrap4 %}

{% block content %}
<div style="text-align: center; max-width: 500px; margin: 4rem auto">
    <div class="mb-4">
        <h4>Update Profile</h4>
    </div>

	<form action="{% url 'profileapp:update' pk=target_profile.pk %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
            {% bootstrap_form form %}
        <input type="submit" class="btn btn-dark rounded-pill col-6 mt-5">
    </form>
</div>

{% endblock %}

urls

프로젝트 설정 디렉토리의 urls.py의 소스코드를 추가하도록 할게요.
이 작업은 뭐냐?🐨

한 마디로 이미지 파일이 브라우저에 표현되기 위해서 하는 url 작업입니다.👽
그럼 어떻게 하냐고요?🐮

일단 봅시다.👻

방법1과 방법2는 결론적으로 동일하게 accounsts/detail/pk에서 이미지를 보여줘요.

차이점은 방법1의 경우 추후 배포나 운영시에 또 url을 손 봐야한다는거고요.
DEBUG 모드가 True, False에 상관없이 로컬 환경에서 연결된 이미지를 보여줘요.

방법2는 DEBUG = False 모드인 경우 로컬에서 사진을 당겨오지 않으니 참 편리하겠주?🐱

방법1

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),

    path('accounts/', include('accountapp.urls')),
    path('profiles/', include('profileapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

방법2

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),

    path('accounts/', include('accountapp.urls')),
    path('profiles/', include('profileapp.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

template

그럼 정작 우리가 확인해야 할 유저의 프로필 이미지는 어디일까요?

accountapp에 있는 detail.html 파일을 수정할게요.

**

{% extends 'base.html' %}

{% block content %}

    <div>
	    <div style="text-align: center; max-width: 500px; margin: 4rem auto;">

            <img src=" {{ target_user.profile.image.url }}" alt=""
            style="height: 10rem; width: 10rem; border-radius: 10rem; margin-bottom: 2rem;">
            {% if target_user.profile %}
	    	    <h2 style="font-family: 'NanumSquareB'">
                    {{target_user.profile.nickname }}
                    <a href="{% url 'profileapp:update' pk=target_user.profile.pk %}">
                        edit
                    </a>
                </h2>
            {% else %}
                <a href="{% url 'profileapp:create' %}"> <h4 style="font-family: 'NanumSquareB'">Create Profile</h4> </a>
            {% endif %}
            <h4 style="margin-bottom: 3rem;">
                {{ target_user.profile.message }}
            </h4>

            {% if target_user == user %}
            <a href="{% url 'accountapp:update' pk=target_user.pk %}">
                <p>Account Info</p>
            </a>
            <a href="{% url 'accountapp:delete' pk=target_user.pk %}">
                <p>Delete</p>
            </a>
            {% endif %}
	    </div>
</div>



{% endblock %}

출력결과
음...🙈 일단 원하는 대로 소스코드는 잘 돌아 간것 같군요.

View - 2

보고 또 봐야하는 뷰!!🤔

그렇다면 로그인 하지 않은 사람이 혹은 다른 로그인 유저가 나의 프로필이미지, 닉네임, 메시지를 바꾸면 안되겠조?

그걸 방지하기위한 인증 절차를 데코레이터로 구현할게요. 예전에 한번 했어요~

profile_ownership_required는 뭘까요?
바로! decorators.py 파일을 만들어 구현해야할 데코레이터 이름입니다!


# 생략

@method_decorator(profile_ownership_required, 'get')
@method_decorator(profile_ownership_required, 'post')
class ProfileUpdateView(UpdateView):
    model = Profile
    context_object_name = 'target_profile'
    form_class = ProfileCreationForm
    success_url = reverse_lazy('accountapp:hello_world')
    template_name = 'profileapp/update.html'

decorator

아래와 같이 데코레이터를 구현합니다~~ 그리고 바로 위 view의 ProfileUpdateView 클래스의 머리위에 처럼 @method_decorator의 첫번째 인자로 살포시 안착하쥬~?!!👨🏿‍🤝‍👨🏿👩🏾‍🤝‍🧑🏼👩🏻‍🤝‍🧑🏻

profileapp/decorator.py

from django.http import HttpResponseForbidden

from profileapp.models import Profile


def profile_ownership_required(func):
    def decorated(request, *args, **kwargs):
        profile = Profile.objects.get(pk=kwargs['pk']) 
        if not profile.user == request.user: 
            return HttpResponseForbidden()
        return func(request, *args, **kwargs)
    return decorated
profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글