Accountapp implementation

jurin·2021년 4월 1일
0

Django Project - LeeBook

목록 보기
2/11

실용주의 프로그래머님의 인프런 강의를 듣고 작성하였습니다.
출처: https://www.inflearn.com/course/%EC%9E%A5%EA%B3%A0-%ED%95%80%ED%84%B0%EB%A0%88%EC%8A%A4%ED%8A%B8/lecture/62871?tab=note&speed=1.25

회원가입 구현

CreateView 사용

class AccountCreateView(CreateView):
    model = User
    form_class = UserCreationForm
    success_url = reverse_lazy('accountapp:hello_world')
    template_name = 'accountapp/create.html'

회원가입 경로 설정

urlpatterns = [
    path('hello_world/', hello_world, name='hello_world')
    # "127.0.0.1:8000/account/hello_world"
    
    path('create/', AccountCreateView.as_view(), name='create')
]

create.html 생성

{% extends 'base.html' %}

{% block content %}

    <div style="text-align: center">
        <form action="{% url 'accountapp:create' %}" method="post">
            {% csrf_token %}
            {{ form }}

            <input type="submit" class="btn btn-primary">
        </form>
    </div>

{% endblock %}

header.py에서 회원 가입 경로 추가

{% if not user.is_authenticated %}
            <a href="{% url 'accountapp:login' %}?next={{ request.path }}">
                <span>login</span>
            </a>
            <a href="{% url 'accountapp:create' %}">
                <span>Sign Up</span>
            </a>
            {% else %}

로그인, 로그아웃

urls.py에 경로 추가

urlpatterns = [
    path('hello_world/', hello_world, name='hello_world'),
    # "127.0.0.1:8000/account/hello_world"

    path('login/', LoginView.as_view(template_name="accountapp/login.html"), name='login'),
    path('logout/', LogoutView.as_view(), name='logout'),

    path('create/', AccountCreateView.as_view(), name='create')
]

로그인 뷰와 로그아웃 뷰에서 경로를 지정해 주어야 한다.
1. next
2. LOGIN_REDIRECT_URL
3. Default

아무것도 지정해 주지 않으면 Default로 간다. 따라서 위의 우선순위대로 경로를 지정해주자.

next는 ?next={{ request.path }} 구문을 통해 현재 url로 돌아오도록 해준다.

LOGIN_REDIRECT_URL은 leebook/settings.py에서 설정해준다.

LOGIN_REDIRECT_URL = reverse_lazy('accountapp:hello_world')
LOGOUT_REDIRECT_URL = reverse_lazy('accountapp:login')

메인 페이지에 로그인, 로그아웃 버튼

            {% if not user.is_authenticated %}
            <a href="{% url 'accountapp:login' %}?next={{ request.path }}">
                <span>login</span>
            </a>
            {% else %}
            <a href="{% url 'accountapp:logout' %}?next={{ request.path }}">
                <span>logout</span>
            </a>
            {% endif%}

login.html 생성

{% extends 'base.html'%}

{% block content %}

    <div style="text-align: center">
        <div>
            <h4>Login</h4>
        </div>
        <div>
            <form action="" method="post">
                {% csrf_token %}
                {{ form }}
                <input type="submit" class="btn btn-primary">
            </form>
        </div>

    </div>

{% endblock %}

Bootstrap

설치

pip install django-bootstrap4

setting.py에 bootstrap4 추가

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap4',
    'accountapp',
]

부트스트랩 적용

create.html

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


{% block content %}

    <div style="text-align: center; max-width: 500px; margin: 4rem auto">
        <div class="mb-4">
            <h4>
                SignUp
            </h4>
        </div>
        <form action="{% url 'accountapp:create' %}" method="post">
            {% csrf_token %}
            {% bootstrap_form form %}

            <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
        </form>
    </div>

{% endblock %}

login.html

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

{% block content %}

    <div style="text-align: center; max-width: 500px; margin: 4rem auto">
        <div>
            <h4>Login</h4>
        </div>
        <div>
            <form action="" method="post">
                {% csrf_token %}
                {% bootstrap_form form %}
                <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
            </form>
        </div>

    </div>

{% endblock %}

font 적용

다운받은 폰트 static/fonts에 저장

head.html 파일에 추가해서 어디서든 font 사용할 수 있도록 하기

    <style>
        @font-face {
            font-family: 'NanumSquareR';
            src: local('NanumSquareR'),
            url("{% static 'fonts/NanumSquareR.ttf' %}") format("opentype");
        }
        @font-face {
            font-family: 'NanumSquareEB';
            src: local('NanumSquareEB'),
            url("{% static 'fonts/NanumSquareEB.otf' %}") format("opentype");
        }
        @font-face {
            font-family: 'NanumSquareB';
            src: local('NanumSquareB'),
            url("{% static 'fonts/NanumSquareB.otf' %}") format("opentype");
        }
        @font-face {
            font-family: 'NanumSquareR';
            src: local('NanumSquareR'),
            url("{% static 'fonts/NanumSquareR.otf' %}") format("opentype");
        }
    </style>

base.html에서 적용

<body style="font-family: 'NanumSquareR';">

중간에 css를 변경해도 적용되지 않는 오류가 있어서 head.html에서 base.css를 적용하는 링크에 ?after을 적어주니 해결되었다.

    <!-- DEFAULT CSS LINK -->
    <link rel="stylesheet" type="text/css" href="{% static 'base.css' %}?after">

Detail View (Read View)

사용자의 상세 정보를 확인하는 개인 페이지를 만든다.
이를 위해 그 사용자의 primary key가 필요하다. 특정 유저 객체에 부여된 고유한 키가 필요.

  1. Views.py에서 class 생성
class AccountDetailView(DetailView):
    model = User
    template_name = 'accountapp/detail.html'
  1. detail.html 생성
{% extends 'base.html' %}

{% block content %}
    <div style="text-align: center; max-width: 500px; margin: 4rem auto;">
        <div>
            <p>
                {{ user.date_joined }}
            </p>
            <h2 style="font-family: 'NanumSquareB'">
                {{ user.username }}
            </h2>
        </div>
    </div>

{% endblock %}
  1. urls.py에 경로 추가
    pk라는
    고유 키 알아야 접속 가능
path('detail/<int:pk>', AccountDetailView.as_view(), name='detail')

이제 header.html에서 로그인이 안돼있으면 원래 그대로, 로그인이 되어 있으면 Mypage로 향하는 링크를 만들어 준다.

{% else %}
            <a href="{% url 'accountapp:detail' pk=user.pk %}">
                <span>Mypage</span>
            </a>
            <a href="{% url 'accountapp:logout' %}?next={{ request.path }}">
                <span>logout</span>
            </a>
            {% endif%}

context_object_name이라는 것을 통해서 template에서 사용하는 user 객체 이름을 다르게 설정할 수 있다. 다른 사람이 우리 페이지를 오더라도 우리 페이지의 정보를 볼 수 있게 된다.

class AccountDetailView(DetailView):
    model = User
    context_object_name = 'target_user'
    template_name = 'accountapp/detail.html'
        <div>
            <p>
                {{ target_user.date_joined }}
            </p>
            <h2 style="font-family: 'NanumSquareB'">
                {{ target_user.username }}
            </h2>
        </div>

UpdateView

UpdateView를 이용한 비밀번호 변경 구현하기

view.py에서 class 추가

class AccountUpdateView(UpdateView):
    model = User
    context_object_name = 'target_user'
    form_class = UserCreationForm
    success_url = reverse_lazy('accountapp:hello_world')
    template_name = 'accountapp/update.html'

urls.py에서 경로 추가

    path('update/<int:pk>', AccountUpdateView.as_view(), name='update')

update.html 생성

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


{% block content %}

    <div style="text-align: center; max-width: 500px; margin: 4rem auto">
        <div class="mb-4">
            <h4>
                Change Info
            </h4>
        </div>
        <form action="{% url 'accountapp:update' pk=target_user.pk %}" method="post">
            {% csrf_token %}
            {% bootstrap_form form %}

            <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
        </form>
    </div>

{% endblock %}

이제 detail 페이지에서 수정하는 주소로 가는 링크를 작성한다.

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

여기서 문제점은 아이디를 바꿔도 바뀐다는 것이다. 아이디는 바꿀 수 없도록 비활성화 해주는 작업을 한다.

accountapp에 forms라는 파일을 만들어서 views에서 작성을 했던 UpdateView에서 쓰인 form, 즉 UserCreationForm을 상속받아서 forms에서 커스터마이징을 한다.

from django.contrib.auth.forms import UserCreationForm

class AccountUpdateForm(UserCreationForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['username'].disabled = True

이제 UpdateView의 form_class를 AccountUpdateForm로 바꿔준다.

이렇게 비활성화를 해도 전문가 모드에서 그 내용을 바꿀 수 있다. 하지만 그렇게 제출을 해도 아이디는 바뀌지 않는다.

DeleteView

DeleteView를 이용하여 회원 탈퇴 기능을 구현한다.

view.py

class AccountDeleteView(DeleteView):
    model = User
    context_object_name = 'target_user'
    success_url = reverse_lazy('accountapp:login')
    template_name = 'accountapp/delete.html'

urls.py

    path('delete/<int:pk>', AccountDeleteView.as_view(), name='delete')

delete.html 생성

{% extends 'base.html' %}

{% block content %}

    <div style="text-align: center; max-width: 500px; margin: 4rem auto">
        <div class="mb-4">
            <h4>
                Quit
            </h4>
        </div>
        <form action="{% url 'accountapp:delete' pk=user.pk %}" method="post">
            {% csrf_token %}
            <input type="submit" class="btn btn-danger rounded-pill col-6 mt-3">
        </form>
    </div>

{% endblock %}

detail.html에 링크 추가

            <a href="{% url 'accountapp:delete' pk=target_user.pk %}">
                <p>
                     Delete
                </p>
            </a>
profile
anaooauc1236@naver.com

0개의 댓글