14. SignUp

조재훈·2022년 7월 29일
0

Clone_Airbnb

목록 보기
31/31
post-thumbnail

1) Sign Up Form 생성

회원가입 기능을 구현해보자.
users - views.py

class SignUpView(FormView):
    pass

users - urls.py

urlpatterns = [path("signup", views.SignUpView.as_view(), name="signup")]

templates - partials - nav.html

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

    {% if user.is_authenticated %}
        <li><a href="{% url 'users:logout' %}">Log out</a></li>
    {% else %}
        <li><a href="{% url 'users:login' %}">Login</a></li>
        <li><a href="{% url 'users:signup' %}">Sign Up</a></li>
    {% endif %}
</ul>

메인에 sign up이 떴다.

Sign Up 페이지는 아직 안열림.

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 %}
        {{form.as_p}}
        <button>Sign Up</button>
    </form>
{% endblock content %}

views.py에서 SignUp클래스를 추가한다.
users - views.py

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

users - forms.py

class SignUpForm(forms.Form):
    pass

오 ㅋ

users - forms.py

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")


Sign Up 화면에 정보를 입력할 칸이 나타나도록 하자.
users - views.py

class SignUpView(FormView):

    template_name = "users/signup.html"
    form_class = forms.SignUpForm
    success_url = reverse_lazy("core:home")
    initial = {
        "first_name": "Jaewhoon",
        "last_name": "Cho",
        "email": "123@123.com",
        "password": "123",
        "password1": "123",
    }


password는 입력해도 안되서 그냥 지워버렸다.
여기서 반드시 입력해야하는 정보는 Email과 Password이며, Password와 Confirm Password는 일치해야한다.
users - forms.py

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")
        try:
            models.User.objects.get(email=email)
            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

오 ㅋ

2) Sign Up 구현

users - forms.py

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")
        try:
            models.User.objects.get(email=email)
            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

    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)
        user.first_name = first_name
        user.last_name = last_name
        user.save()

users - views.py

class SignUpView(FormView):

    template_name = "users/signup.html"
    form_class = forms.SignUpForm
    success_url = reverse_lazy("core:home")
    initial = {
        "first_name": "Jaewhoon",
        "last_name": "Cho",
        "email": "123@123.com",
    }

    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)


관리자로 로그인되어있던 admin이 로그아웃되고 권한없는 사용자가 로그인중이라고 뜬걸 보니 제대로 되었다.

3) ModelForm

comment, review, message 등 여러 기능을 추가할건데 매번 이렇게 model로 가서 요소들 다 복사한 다음에 붙여넣고 하기가 번거롭다. ModelForm이란걸 써서 간단하게 하자. 말 그대로 Model에 연결된 Form이다.
users - forms.py

class SignUpForm(forms.ModelForm):


그리고 내부에 Meta class를 선언해주자.
users - forms.py

class SignUpForm(forms.ModelForm):
    class Meta:
        model = models.User



흠.... ModelForm을 구성하는데 fields나 execlude가 없어서는 안된다고 한다.

Meta 클래스에 fields를 추가했고 그 아래에 fields에 추가한 변수들은 지워보았다.
users - forms.py

class SignUpForm(forms.ModelForm):
    class Meta:
        model = models.User
        fields = ("first_name", "last_name", "email")

    # 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")

전혀 지장없이 잘 나타난다.

그러면 이제 ModelForm이 email을 자동으로 clean시킬테니 clean_email이 필요가 없어진다. save도 ModelForm에 있는 기능이긴 한데 일단 중복되는건 지우고서 해보자.
users - forms.py

class SignUpForm(forms.ModelForm):
    class Meta:
        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

이 상태에선 유저가 생성은 되는데 Username이 비어있다.

save함수를 override해서 기능을 조정해보자.

commit=False => object를 생성하지만 db에는 등록하지 마라
users - forms.py

class SignUpForm(forms.ModelForm):
    class Meta:
        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)
        email = self.cleaned_data.get("email")
        password = self.cleaned_data.get("password")
        user.username = email
        user.set_password(password)
        user.save()

User 생성해보면 자동으로 username에 email이 들어간 것을 볼 수 있다.

profile
맨땅에 헤딩. 인생은 실전.

0개의 댓글