Tutorial Membuat Halaman Ubah Password dengan Django dan Boostrap 4


Rizqi Maulana
Backend Developer

Pada materi ketiga ini kita akan belajar membuat fitur untuk mengubah password. Untuk membuat fitur ini kita akan melakukan 3 hal yaitu: Membuat class View, menambahkan url baru dan membuat template html untuk halaman web nya. Sama halnya dengan fitur login, kita akan mengkostumisasi class View bawaan dari Django untuk fitur ubah password. Jadi kita akan membuat class yang merupakan class turunan dari class View tersebut. Buka kembali file django_login_register/myauth/views.py dan sesuaikan kodenya menjadi seperti berikut.

django_login_register/myauth/views.py

from django.views import View
from django.shortcuts import render, redirect
from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView
from django.conf import settings
from django.contrib.auth import login, authenticate
from django.urls import reverse_lazy
from django.contrib import messages

from .forms import SignUpForm


class CustomLoginView(LoginView):
	template_name = 'accounts/login.html';
	redirect_authenticated_user = True


class HomeView(View):
    template_name = 'accounts/home.html'

    def get(self, request):
        return render(request, self.template_name)


class CustomLogoutView(LogoutView):
    template_name = 'accounts/login.html'
    next_page = 'login'


class RegisterView(View):
    template_name = 'accounts/register.html'

    def get(self, request):
        form = SignUpForm()
        return render(request, self.template_name, {'form': form})
    
    def post(self, request, *args, **kwargs):
        form = SignUpForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=username, password=raw_password)
            login(request, user)
            return redirect('home')
        
        return render(request, self.template_name, {'form': form})


class CustomPasswordChangeView(PasswordChangeView):
    template_name = 'accounts/change_password.html'
    success_url = reverse_lazy('home')

    def form_valid(self, form):
        messages.success(self.request, 'Password kamu berhasil diubah')
        return super().form_valid(form)

Penjelasan Kode:

  • Pertama kita mengimport beberapa class helper yang dibutuhkan seperti class View untuk fitur ubah password bawaan dari Django (PasswordChangeView) kemudian kita menambahkan 2 function baru yaitu reverse_lazy (untuk menggenerate url) dan messages (untuk menampilkan pesan sukses).

    from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView
    ...
    from django.urls import reverse_lazy
    from django.contrib import messages
    
  • Kedua kita membuat class bernama CustomPasswordChangeView yang merupakan turunan dari class PasswordChangeView. Pada class tersebut kita mengkostumisasi beberapa attribute seperti template_name, success_url (ketika user sukses mengganti password, user akan diarahkan ke url yang di set pada attribute ini) dan terakhir kita meng-override method form_valid dimana kita mengeset pesan sukses "Password kamu berhasil diubah" ketika user berhasil mengubah passwordnya.

    class CustomPasswordChangeView(PasswordChangeView):
        template_name = 'accounts/password_change.html'
        success_url = reverse_lazy('home')
    
        def form_valid(self, form):
            messages.success(self.request, 'Password kamu berhasil diubah')
            return super().form_valid(form)
    

Selanjutnya kita perlu menambahkan juga url baru untuk halaman fitur ubah password ini. Lakukan perubahan pada kode di file django_login_register/myauth/urls.py.

django_login_register/myauth/urls.py

from django.urls import path

# import class View
from .views import CustomLoginView, HomeView, CustomLogoutView, RegisterView, CustomPasswordChangeView

urlpatterns = [
    path('login/', CustomLoginView.as_view(), name='login'),
    path('home/', HomeView.as_view(), name='home'),
    path('logout/', CustomLogoutView.as_view(), name='logout'),
    path('register/', RegisterView.as_view(), name='register'),
    path('password/change/', CustomPasswordChangeView.as_view(), name='password_change'),
]

Penjelasan Kode:

  • Pertama kita mengimport class View yang sudah kita buat sebelumnya (CustomPasswordChangeView)

    from .views import CustomLoginView, HomeView, CustomLogoutView, RegisterView, CustomPasswordChangeView
    
  • Kedua kita menambahkan url baru untuk halaman fitur ubah password dengan baris kode ini.

    urlpatterns = [
        ...
        path('password/change/', CustomPasswordChangeView.as_view(), name='password_change'),
    ]
    

Dan terakhir yang perlu kita buat untuk fitur ubah password ini adalah membuat file template html. Buat sebuah file baru dengan nama password_change.html pada folder django_login_register/myauth/templates/accounts/ dan tuliskan kode berikut.

django_login_register/myauth/templates/accounts/password_change.html

<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->

<style>
    body {
        margin-top: 50px;
    }
</style>
</head>
<body>
<div class="container">
<br>


<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<header class="card-header">
    <a href="{% url 'home' %}" class="float-right btn btn-outline-primary mt-1">Home</a>
	<h4 class="card-title mt-2">Ganti Password</h4>
</header>
<article class="card-body">
{% load widget_tweaks %}
<form method="post" novalidate>
    {% csrf_token %}
	<div class="form-group">
		<label>{{ form.old_password.label }}</label>
	    {% if form.is_bound %}
            {% if form.old_password.errors %}
                {% render_field form.old_password class="form-control is-invalid" %}
            {% else %}
                {% render_field form.old_password class="form-control is-valid" %}
            {% endif %}
        {% else %}
            {% render_field form.old_password class="form-control" %}
        {% endif %}
        {% for error in form.old_password.errors %}
            <div class="invalid-feedback">{{ error }}</div>
        {% endfor %}
    </div> <!-- form-group end.// -->
    <div class="form-group">
		<label>{{ form.new_password1.label }}</label>
	    {% if form.is_bound %}
            {% if form.new_password1.errors %}
                {% render_field form.new_password1 class="form-control is-invalid" %}
            {% else %}
                {% render_field form.new_password1 class="form-control is-valid" %}
            {% endif %}
        {% else %}
            {% render_field form.new_password1 class="form-control" %}
        {% endif %}
        {% for error in form.new_password1.errors %}
            <div class="invalid-feedback">{{ error }}</div>
        {% endfor %}
    </div> <!-- form-group end.// -->  
    <div class="form-group">
		<label>{{ form.new_password2.label }}</label>
	    {% if form.is_bound %}
            {% if form.new_password2.errors %}
                {% render_field form.new_password2 class="form-control is-invalid" %}
            {% else %}
                {% render_field form.new_password2 class="form-control is-valid" %}
            {% endif %}
        {% else %}
            {% render_field form.new_password2 class="form-control" %}
        {% endif %}
        {% for error in form.new_password2.errors %}
            <div class="invalid-feedback">{{ error }}</div>
        {% endfor %}
	</div> <!-- form-group end.// -->  
    <div class="form-group">
        <button type="submit" class="btn btn-primary btn-block"> Ubah  </button>
    </div> <!-- form-group// -->                                             
</form>
</article> <!-- card-body end .// -->
</div> <!-- card.// -->
</div> <!-- col.//-->

</div> <!-- row.//-->


</div> 
<!--container end.//-->
</body>
</html>

Penjelasan Kode:

  • Dari kode di atas kita membuat template untuk halaman ubah password dimana terdapat satu tombol untuk kembali ke halaman home dan juga kita menambahkan kode untuk merender form ubah password.

Kita juga perlu sedikit melakukan perubahan pada file template django_login_register/myauth/templates/accounts/home.html. Buka file tersebut dan sesuaikan kodenya seperti di bawah ini.

django_login_register/myauth/templates/accounts/home.html

<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/all.css">

<style>
    body {
        margin-top: 50px;
    }
    .card-body {
        min-height: 300px;
    }
</style>
</head>
<body>
<div class="container">
<br>


<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<header class="card-header">
	<a href="{% url 'logout' %}" class="float-right btn btn-outline-primary mt-1">Log out</a>
	<h4 class="card-title mt-2">{{ user.username }}</h4>
</header>
<article class="card-body">
    <div>
        {% if messages %}
        
          {% for message in messages %}
          <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
              {{ message | safe }}
          </div>
          {% endfor %}
       
        {% endif %}
    </div>
    
    <p>Selamat datang di website kami. Silahkan kunjungi <a href="https://santrikoding.com" target="_blank">santrikoding.com</a> untuk mencari tutorial yang berkualitas dengan harga yang bersahabat.</p>

    <div>
        <a href="{% url 'password_change' %}" class="btn btn-primary">Ubah Password</a>
    </div>
</article> <!-- card-body end .// -->
</div> <!-- card.// -->
</div> <!-- col.//-->

</div> <!-- row.//-->


</div> 
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
<!--container end.//-->
</body>
</html>

Penjelasan Kode:

  • Pertama kita menambahkan kode berikut untuk menampilkan pesan sukses jika password berhasil diubah.

    <div>
        {% if messages %}
    
          {% for message in messages %}
          <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
              {{ message | safe }}
          </div>
          {% endfor %}
    
        {% endif %}
    </div>
    
  • Kedua kita menambahkan tombol "Ubah Password" yang jika kita klik akan mengarah ke halaman ubah password.

    <div>
        <a href="{% url 'password_change' %}" class="btn btn-primary">Ubah Password</a>
    </div>
    

Sekarang coba login kembali dan dari halaman home klik tombol "Ubah Password" maka akan tampil halaman ubah password seperti gambar di bawah ini.

Halaman Ubah Password

Ketika kita sukses mengubah password kita maka seharusnya kita akan diarahkan kembali ke halaman home dan di halaman tersebut akan muncul pesan sukses seperti gambar di bawah ini.

Pesan Sukses Ubah Password Pada Halaman Home

Kamu bisa mendownload source code untuk materi ini pada link berikut https://github.com/sakukode/django-login-register/tree/chapter/03-ubah-password


Ebook Django Rp. 99.000

Django Rest API - Studi Kasus Portal Berita* : https://bit.ly/django-rest-api-portal-berita


Rizqi Maulana
Backend Developer

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami

KOMENTAR