FormView

Jeong Ha Seung·2021년 11월 26일

Login Form

config/urls.py

...
urlpatterns=[...    path("users/", include("users.urls", namespace="users")),]

templates/partials/nav.html

<a href="{% url "core:home" %}">Nbnb</a>
<ul>
    <li><a href="{% url "users:login" %}">Login</a></li>
</ul>

users/urls.py

from django.urls import path
from . import views

app_name = "users"

urlpatterns = [
    path("login", views.LoginView.as_view(), name="login"),
    path("logout", views.log_out, name="logout"),
]

templates/users/login.html

{% extends "base.html" %}

{% block page_title %}
    Log In
{% endblock page_title %}

{% block search-bar %}
{% endblock search-bar %}

{% block content %}

    Hello!


{% endblock content %}  

users/views.py

from django.views import View
from django.views.generic import FormView #FormView import 
from django.urls import reverse_lazy
from django.shortcuts import render, redirect, reverse
from django.contrib.auth import authenticate, login, logout
from . import forms


class LoginView(FormView):

    template_name = "users/login.html" #rendering되는 html
    form_class = forms.LoginForm #사용할 Form 지정
    success_url = reverse_lazy("core:home") #인증완료 시 이동할 경로 지정

    def form_valid(self, form): #내장 method인 form_valid를 통해 유효성 검사 진행
        email = form.cleaned_data.get("email")
        password = form.cleaned_data.get("password")
        user = authenticate(self.request, username=email, password=password)
        if user is not None:
            login(self.request, user)
        return super().form_valid(form)


def log_out(request):
    logout(request)
    return redirect(reverse("core:home"))
    

users/forms.py

from django import forms
from . import models


class LoginForm(forms.Form):

  email = forms.EmailField()
  password = forms.CharField(widget=forms.PasswordInput)

  def clean(self):
      email = self.cleaned_data.get("email") # 👈 유효성 검사를 진행한 email field에 값을 추출한다.
      password = self.cleaned_data.get("password") # 👈 유효성 검사를 진행한 password field에 값을 추출한다.
      try:
          user = models.User.objects.get(email=email) # 👈 emil을 기준으로 해당 Object를 가져온다.

          if user.check_password(password):  # 👈 비밀번호가 서로 일치하다면 True, 아니면 False 반환
              return self.cleaned_data
          else:
              self.add_error("password", forms.ValidationError("Password is wrong"))
      except models.User.DoesNotExist:
          self.add_error("email", forms.ValidationError("User does not exist"))

Sign Up Form

templates/partials/nav.html

<a href="{% url "core:home" %}">Nbnb</a>
<ul>

    {% if user.is_authenticated %}
        <li><a href="{% url "users:logout" %}">Log out</a></li>
    {% else %}
        <li><a href="{% url "users:login" %}">Log in</a></li>
        <li><a href="{% url "users:signup" %}">Sign up</a></li> #다음과 같이 추가, 로그인 된 상태에서는 보일 필요가 없음
    {% endif %}


</ul>

templates/users/signup.html

{% extends "base.html" %}

{% block page_title %}
    Sign Up
{% endblock page_title %}

{% block search-bar %}
{% endblock search-bar %}

{% block content %}
    <form method="POST" action="{% url "users:signup" %}">
        {% csrf_token %} #서버의 보안을 위해 POST로 데이터를 전송할 때는 {% csrf_token %}을 반드시 넣어줘야한다. 넣지 않으면 에러가 발생한다
        {{form.as_p}}
        <button>Sign up</button>
    </form>
{% endblock content %} 

users/forms.py

from django import forms
from . import models


class LoginForm(forms.Form):

    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)

    def clean(self):
        email = self.cleaned_data.get("email")
        password = self.cleaned_data.get("password")
        try:
            user = models.User.objects.get(email=email)
            if user.check_password(password):
                return self.cleaned_data
            else:
                self.add_error("password", forms.ValidationError("Password is wrong"))
        except models.User.DoesNotExist:
            self.add_error("email", forms.ValidationError("User does not exist"))


class SignUpForm(forms.Form):

    first_name = forms.CharField(max_length=80)
    last_name = forms.CharField(max_length=80)
    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)
    password1 = forms.CharField(widget=forms.PasswordInput, label="Confirm Password")

    def clean_email(self):
        email = self.cleaned_data.get("email") #field의 입력값 가져오기
        try:
            models.User.objects.get(email=email) #필드의 email값이 DB에 존재하는지 확인
            raise forms.ValidationError("User already exists with that email")
        except models.User.DoesNotExist:
            return email #존재하지 않는다면, 데이터를 반환시킨다.

    def clean_password1(self):
        password = self.cleaned_data.get("password")
        password1 = self.cleaned_data.get("password1")
        if password != password1:
            raise forms.ValidationError("Password confirmation does not match")
        else:
            return password
	# save method로 DB에 저장
    def save(self):
        first_name = self.cleaned_data.get("first_name")
        last_name = self.cleaned_data.get("last_name")
        email = self.cleaned_data.get("email")
        password = self.cleaned_data.get("password")
        user = models.User.objects.create_user(email, email, password) 
        #"create_user"는 id, email, password를 순서대로 전달해줘야 한다.
        user.first_name = first_name
        user.last_name = last_name
        user.save()
            

users/urls.py

urlpatterns = [
    path("login", views.LoginView.as_view(), name="login"),
    path("logout", views.log_out, name="logout"),
    path("sigup", views.SignUpView.as_view(), name="signup"), #다음과 같이 추가
]

users/views.py

from django.views.generic import FormView
from django.urls import reverse_lazy
from django.shortcuts import redirect, reverse
from django.contrib.auth import authenticate, login, logout
from . import forms


class LoginView(FormView):

    template_name = "users/login.html"
    form_class = forms.LoginForm
    success_url = reverse_lazy("core:home")

    def form_valid(self, form):
        email = form.cleaned_data.get("email")
        password = form.cleaned_data.get("password")
        user = authenticate(self.request, username=email, password=password)
        if user is not None:
            login(self.request, user)
        return super().form_valid(form)


def log_out(request):
    logout(request)
    return redirect(reverse("core:home"))


class SignUpView(FormView):

    template_name = "users/signup.html"
    form_class = forms.SignUpForm
    success_url = reverse_lazy("core:home")
	...

    def form_valid(self, form):
        form.save()
        email = form.cleaned_data.get("email")
        password = form.cleaned_data.get("password")
        user = authenticate(self.request, username=email, password=password)
        if user is not None:
            login(self.request, user)
        return super().form_valid(form)
        

ModelForm을 상속받아 SignUp 구현

users/forms.py

from django import forms
from . import models


class LoginForm(forms.Form): 

    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)

    def clean(self):
        email = self.cleaned_data.get("email")
        password = self.cleaned_data.get("password")
        try:
            user = models.User.objects.get(email=email)
            if user.check_password(password):
                return self.cleaned_data
            else:
                self.add_error("password", forms.ValidationError("Password is wrong"))
        except models.User.DoesNotExist:
            self.add_error("email", forms.ValidationError("User does not exist"))


class SignUpForm(forms.ModelForm): # ModelForm을 상속하면 Model을 활용할 수 있음.
    class Meta: # 연결할 Model과 사용할 fields를 지정
        model = models.User
        fields = ("first_name", "last_name", "email")

    password = forms.CharField(widget=forms.PasswordInput)
    password1 = forms.CharField(widget=forms.PasswordInput, label="Confirm Password")

    def clean_password1(self):
        password = self.cleaned_data.get("password")
        password1 = self.cleaned_data.get("password1")
        if password != password1:
            raise forms.ValidationError("Password confirmation does not match")
        else:
            return password

    def save(self, *args, **kwargs):
        user = super().save(commit=False) # "commit=False"는 Object는 생성하지만 저장하지 않은 상태
        email = self.cleaned_data.get("email")
        password = self.cleaned_data.get("password")
        user.username = email
        user.set_password(password) # set_password는 비밀번호를 hash값으로 변경
        user.save()
profile
블로그 이전했습니다. https://morethan-haseung-log.vercel.app

0개의 댓글