ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • django change password by FBV
    Project using python/Cloning Airbnb 2021. 3. 5. 14:08

    url 설정

    config/urls.py

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

    users/urls.py

    from django.urls import path
    from . import views
    
    app_name = "users"
    
    urlpatterns = [path("<int:pk>/change-password/", views.change_password, name="change-password")]
    

    {% url %}

      update_profile.html의 일부다. Change Password button을 누르면 password를 수정할 수 있는 page로 간다. url template tag를 이용해서 update_profile page로 갈 수 있게 한다. {% url 'users:change-password' user.pk %}는 /users/<int:pk>/change-password/와 같다.

    FBV(Function Based View)

    users/views.py

      FBV에서는 if 문으로 GET method 요청이 왔을 때와 POST method 요청이 왔을 때를 구분한다. GET은 page를 보여주고 POST는 client로부터 온 data를 처리한다.

    # users/views.py
    
    from django.shortcuts import render, redirect, reverse
    from django.contrib.auth import authenticate, login
    from django.contrib import messages
    from .exception import VerifyUser
    
    class EmailLoggedInOnly(Exception):
        pass
    
    
    @login_required
    def change_password(request, pk):
        if request.method == "GET":
            try:
                if request.user.login_method != "email":
                    raise EmailLoggedInOnly("Page not found 404")
                if request.user.pk != pk:
                    raise VerifyUser("Page Not found 404")
                user = models.User.objects.get_or_none(pk=pk)
                if user is None:
                    messages.error(request, "User does not exist")
                    return redirect(reverse("core:home"))
                return render(
                    request,
                    "pages/users/change_password.html",
                    context={"user": user},
                )
            except VerifyUser as error:
                messages.error(request, error)
                return redirect("core:home")
            except EmailLoggedInOnly as error:
                messages.error(request, error)
                return redirect("core:home")
        elif request.method == "POST":
            try:
                if request.user.login_method != "email":
                    raise EmailLoggedInOnly("Page not found 404")
                if request.user.pk != pk:
                    raise VerifyUser("Page Not found 404")
                user = models.User.objects.get_or_none(pk=pk)
                if user is None:
                    messages.error(request, "User does not exist")
                    return redirect(reverse("core:home"))
                old_password = request.POST.get("current_password")
                new_password = request.POST.get("new_password")
                new_password1 = request.POST.get("verify_password")
                user = authenticate(request, username=user.email, password=old_password)
                if user is None:
                    raise ChangePasswordException("Current password is wrong!")
    
                if new_password != new_password1:
                    raise ChangePasswordException("New password doesn't match")
                user.set_password(new_password)
                user.save()
                messages.success(request, f"{user.email}'password changed successfully")
                login(request, user)
                return redirect(reverse("users:profile", kwargs={"pk": pk}))
            except ChangePasswordException as error:
                messages.error(request, error)
                return redirect(reverse("core:home"))
            except VerifyUser as error:
                messages.error(request, error)
                return redirect("core:home")
            except EmailLoggedInOnly as error:
                messages.error(request, error)
                return redirect("core:home")

    templates

    pages/users/change_password.html

      {% csrf_token %}은 csrf 공격을 막기 위한 token이다. django는 보안이 뛰어나기 때문에 {% csrf_token %} tag를 사용하지 않으면 submit이 안 된다. csrf 공격의 보안은 절대 client를 신뢰하지 않는 것으로 시작한다. 즉, 이 token 값을 가지지 않은 브라우저 요청은 받아들이지 않는다.

    {% extends 'base.html' %}
    
    
    {% block page_title %}
      Change {{user.first_name}}'s Password
    {% endblock page_title %}
      
    {% block search-bar %}
    <div></div>
    {% endblock search-bar %}
    
    {% block content %}
      <div class="background">
        <div class="wrap">
          <h1 class="font-bold text-xl mb-6">Change password of {{user.email}}</h1>
          <form method="post" class="form">
            {% csrf_token %}
            <div class="form_input rounded-tl-lg rounded-tr-lg">
              <input type="password" name="current_password" id="current_password" placeholder="Your current password">
            </div>
    
            <div class="form_input">
              <input type="password" name="new_password" id="new_password" placeholder="New password">
            </div>
    
            <div class="form_input rounded-bl-lg rounded-br-lg">
              <input type="password" name="verify_password" id="verify_password" placeholder="Verify your new password">
            </div>
            <button class="form_button bg-red-500">Change Password</button>
          </form>
          <button class="button bg-gray-700">
            <a href="{% url 'users:profile' user.pk %}">Back</a>
          </button>
        </div>
      </div>
    
    {% endblock content %}
      

     

    참고 자료

    소스 코드

    github.com/zpskek/airbnb-clone-v3/commit/6f1a9c78929d793322dd95f979b4cba93325c6fc

    'Project using python > Cloning Airbnb' 카테고리의 다른 글

    django room detail by FBV  (0) 2021.03.06
    django change password by CBV  (0) 2021.03.05
    django update profile by CBV  (0) 2021.03.05
    django Update Profile by FBV  (0) 2021.03.05
    django user profile CBV  (0) 2021.03.04

    댓글

Designed by Tistory.