Tutorial Membuat Halaman Login dengan Django dan Boostrap 4


Rizqi Maulana
Backend Developer

Framework Django sudah terintegrasi dengan fitur autentikasi secara bawaan. Mulai dari Model, Migration, Form dan juga View. Kita bisa menggunakan fitur yang sudah ada atau kita bisa mengcustomisasi sesuai dengan kebutuhan pada aplikasi kita. Di tutorial ini kita akan belajar membuat fitur login dan register serta fitur untuk mengubah password menggunakan Django Authentication yang akan sedikit kita lakukan customisasi.

Setting Project

Pada tutorial kali ini, saya tidak akan menjelaskan secara detail langkah instalasi framework Django dan membuat sebuah project baru. Kita akan menggunakan project yang sudah ada. Kamu bisa mendownloadnya atau mengcloningnya pada repository berikut : https://github.com/sakukode/starter-project-django . Atau jika kamu ingin belajar cara menginstal framework Django dan membuat project Django dari awal kamu bisa mengikuti tutorial berikut: [Tutorial CRUD dengan Django dan Boostrap 4 #1: Instalasi dan Membuat Project Baru] (https://santrikoding.com/tutorial-crud-dengan-django-dan-boostrap-4-1-instalasi-dan-membuat-project-baru)

buka terminal/command prompt, kemudian ketikkan perintah berikut.

git clone https://github.com/sakukode/starter-project-django.git django_login_register

Perintah di atas digunakan untuk mengcloning project django yang sudah penulis siapkan dan memindahkannya ke dalam folder dengan nama django_login_register.

Masuk ke dalam folder django_login_register

cd django_login_register

Buat virtual environment di dalam folder tersebut dan aktifkan

python -m venv .env
source .env/bin/activate

Kemudian kita perlu mengubah sedikit kode pada file requirements.txt menjadi seperti berikut.

Django
django-widget-tweaks

Pada kode di atas kita menambahkan package django-widget-tweaks yang nantinya berguna untuk merender Django form ke template html dengan menggunakan style dari class Bootstrap 4.

Terakhir jalankan perintah berikut untuk menginstal Django

pip install -r requirements.txt

Kemudian jangan lupa untuk menjalankan migration dengan perintah berikut.

./manage.py migrate

Cek instalasi Django dengan menjalankan perintah berikut.

./manage.py runserver

Output yang benar:

(env) sakukode@sakukode:~/django_login_register$ ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
February 21, 2021 - 09:22:51
Django version 3.1.7, using settings 'app.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Untuk tampilan atau template pada tutorial ini kita akan menggunakan framework css Bootstrap 4. Kamu bisa membuat template km sendiri atau kamu bisa menggunakan template yang tersedia pada tutorial ini.

Karena kita akan mengcustomisasi fitur bawaan dari Django, maka kita perlu membuat aplikasi baru pada project Django kita. ketikkan perintah di bawah ini untuk membuat aplikasi baru.

django-admin startapp myauth

Struktur folder dari project Django kita akan terlihat seperti gambar di bawah ini.

├── app
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── myauth
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── README.md
└── requirements.txt

Jangan lupa tambahkan aplikasi kita dan juga package widget_tweaks pada bagian INSTALLED_APPS dari file app/settings.py dari project kita.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Aplikasi Untuk Kustomisasi Autentikasi
    'myauth.apps.MyauthConfig',
    # Package django-widget-tweaks
    'widget_tweaks'
]

Membuat Halaman Login

Sekarang kita akan membuat fitur login pada aplikasi kita. Seperti yang sudah kita bahas sebelumnya, Django mempunya fitur autentikasi secara bawaan termasuk fitur untuk login. Django sudah menyediakan Form, View dan Url untuk fitur login. Tetapi disini kita akan melakukan kostumisasi terutama dari segi tampilan dan url.

Buka file django_login_register/myauth/views.py dan tuliskan kode seperti berikut.

django_login_register/myauth/views.py

from django.contrib.auth.views import LoginView


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

Penjelasan kode:

  • Pertama kita menuliskan kode untuk mengimport class LoginView, LoginView ini adalah class View bawaan dari Django untuk login.

    from django.contrib.auth.views import LoginView
    
  • Kedua kita membuat class View baru dengan nama CustomLoginView, dimana class tersebut merupakan class turunan dari class LoginView. dan kita melakukan kostumisasi dengan mengubah value dari beberapa attribute.

    • template_name: attribute ini adalah nama template yang akan digunakan untuk fitur login. Defaultnya adalah registration/login.html
    • redirect_authenticated_user: attribute ini adalah pengaturan untuk mengontrol ketika ada user yang sudah login mengakses halaman login,dia akan dialihkan ke halaman lain yang sudah diatur (misal ke halaman beranda/home). defaultnya adalah False.
    class CustomLoginView(LoginView):
    	template_name = 'accounts/login.html';
    	redirect_authenticated_user = True
    

Kita perlu membuat file template untuk halaman login. buat folder templates di dalam folder django_login_register/myauth dan folder accounts di dalamnya. Kemudian buat file baru django_login_register/myauth/templates/accounts/login.html dan tuliskan kode berikut.

django_login_register/myauth/templates/accounts/login.html

<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<!------ 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;
    }
</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">
	<h4 class="card-title mt-2">Log in</h4>
</header>
<article class="card-body">

<div>
    {% if form.errors %}
    <div class="alert alert-danger">
        Username atau Password kamu salah. Silahkan coba kembali.
    </div>
    {% endif %}
</div>
{% load widget_tweaks %}
<form method="post" action="{% url 'login' %}" novalidate>
    {% csrf_token %}
	<div class="form-group">
		<label>{{ form.username.label_tag }}</label>
        {% if form.is_bound %}
            {% if form.username.errors %}
                {% render_field form.username class="form-control is-invalid" %}
            {% else %}
                {% render_field form.username class="form-control is-valid" %}
            {% endif %}
        {% else %}
            {% render_field form.username class="form-control" %}
        {% endif %}
	</div> <!-- form-group end.// -->
	<div class="form-group">
		<label>{{ form.password.label_tag }}</label>
	    {% if form.is_bound %}
            {% if form.password.errors %}
                {% render_field form.password class="form-control is-invalid" %}
            {% else %}
                {% render_field form.password class="form-control is-valid" %}
            {% endif %}
        {% else %}
            {% render_field form.password class="form-control" %}
        {% endif %}
	</div> <!-- form-group end.// -->  
    <div class="form-group">
        <input type="hidden" name="next" value="{{ next }}">
        <button type="submit" class="btn btn-primary btn-block"> Login  </button>
    </div> <!-- form-group// -->                                             
</form>
</article> <!-- card-body end .// -->
<div class="border-top card-body text-center">Belum punya akun? <a href="#">Sign Up</a></div>
<div class="border-top card-body text-center"><a href="#">Lupa Password?</a></div>
</div> <!-- card.// -->
</div> <!-- col.//-->

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

</div> 
<!--container end.//-->
<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>
</body>
</html>

Penjelasan Kode

  • Pada bagian kode di bawah ini digunakan untuk menampilkan pesan error ketika user memasukkan username dan password yang salah.

    <div>
        {% if form.errors %}
        <div class="alert alert-danger">
            Username atau Password kamu salah. Silahkan coba kembali.
        </div>
        {% endif %}
    </div>
    
  • Dan selanjutnya pada bagian form, pertama kita memanggil method widget_tweaks kemudian di dlm form kita menyisipkan input hidden crsf_token dengan tag csrf_token untuk keamanan form. dan kita juga menambahkan kode untuk merender form username dan password dari variabel form (Django form) ke dalam syntak html.

    {% load widget_tweaks %}
    <form method="post" action="{% url 'login' %}" novalidate>
        {% csrf_token %}
    	<div class="form-group">
    		<label>{{ form.username.label_tag }}</label>
            {% if form.is_bound %}
                {% if form.username.errors %}
                    {% render_field form.username class="form-control is-invalid" %}
                {% else %}
                    {% render_field form.username class="form-control is-valid" %}
                {% endif %}
            {% else %}
                {% render_field form.username class="form-control" %}
            {% endif %}
    	</div> <!-- form-group end.// -->
    	<div class="form-group">
    		<label>{{ form.password.label_tag }}</label>
    	    {% if form.is_bound %}
                {% if form.password.errors %}
                    {% render_field form.password class="form-control is-invalid" %}
                {% else %}
                    {% render_field form.password class="form-control is-valid" %}
                {% endif %}
            {% else %}
                {% render_field form.password class="form-control" %}
            {% endif %}
    	</div> <!-- form-group end.// -->  
        <div class="form-group">
            <input type="hidden" name="next" value="{{ next }}">
            <button type="submit" class="btn btn-primary btn-block"> Login  </button>
        </div> <!-- form-group// -->                                             
    </form>
    

Langkah selanjutnya, buat file baru dengan nama urls.py di dalam folder django_login_register/myauth. kemudian tambahkan kode di bawah ini.

from django.urls import path

# import class View
from .views import CustomLoginView

urlpatterns = [
    path('login/', CustomLoginView.as_view(), name='login'),
]

Penjelasan Kode

  • Pertama kita mengimport function path untuk membuat route baru
  • Kita juga perlu mengimport CustoLoginView yang sudah kita buat sebelumnya
  • Terakhir kita menambahkan sebuah route baru dengan tujuan url login/ yang akan diarahkan ke class CustomLoginView dan kita berikan nama login untuk route tersebut.

Tambahkan url dari aplikasi kita ke dalam pengaturan url project. Buka file django_login_register/app/urls.py. Ubah menjadi seperti kode di bawah ini.

"""app URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls.conf import include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myauth.urls'))
]

Penjelasan Kode

  • Mengimport function include untuk mengimport url dari aplikasi kita.

    from django.urls.conf import include
    
  • Kita menambahkan urls dari aplikasi kita (myauth/urls.py) sehingga semua url atau route yang kita tulis pada file django_login_register/myauth/urls.py akan otomatis dipanggil pada django_login_register/app/urls.py

    path('', include('myauth.urls'))
    

Setelah selesai membuat form login, tentunya kita perlu mengetesnya. Tapi untuk saat ini kita belum membuat form untuk registrasi atau membuat user baru. Nah gimana caranya membuat user baru tanpa form register?Kamu gak perlu bingung karena Django menyediakan fitur untuk membuat user baru dari perintah di terminal seperti ini.

./manage.py createsuperuser

Selanjutnya kamu akan diminta memasukkan Username, Email address, Password dan Konfirmasi password seperti gambar di bawah ini.

(.env) sakukode@sakukode:~/django_login_register$ ./manage.py createsuperuser
Username (leave blank to use 'sakukode'): admin
Email address: admin@santrikoding.com
Password: 
Password (again): 
Superuser created successfully.
(.env) sakukode@sakukode:~/django_login_register$ 

Oke sekarang kita jalankan lagi project Django kita dan buka url berikut dari browser http://127.0.0.1:8000/login maka akan tampil halaman form login seperti gambar di bawah ini.

Halaman Form Login

Coba kamu masukkan username dan password yang salah. Maka akan muncul pesan error seperti gambar di bawah ini.

Halaman Form Login dengan Pesan Error

Dan sekarang coba masukkan username dan password yang benar. Maka tampilannya akan seperti gambar di bawah ini.

Halaman Error Setelah Sukses Login

Mungkin kamu bingung kenapa bisa muncul halaman error seperti di atas setelah kita berhasil login dengan username dan password yang benar. Jawabannya karena secara default class LoginView bawaan Django akan meredirect atau mengalihkan ke url account/profile ketika proses login sukses. Dan karena kita tidak membuat halaman untuk menangani url account/profile maka Django akan mengalihkan ke halaman Page not found . Untuk mengatasi permasalahan di atas kita akan membuat sebuah halaman home sederhana dan kita akan mengubah default redirect url ketika kita sukses melakukan login.

Pertama buka file settings.py pada folder django_login_register/app dan tambahkan satu baris kode berikut di bagian paling bawah.

LOGIN_REDIRECT_URL = 'home'

Kode di atas berguna untuk mengubah default url ketika sukses melakukan login. Jadi kita ubah yang secara default di arahkan ke url account/profile kita ganti ke url home. Oleh karena itu, selanjutnya kita perlu membuat sebuah halaman home sebagai halaman tujuan setelah kita berhasil melakukan login.

Buka file django_login_register/myauth/views.py dan ubah kode nya menjadi seperti di bawah ini.

from django.views import View
from django.shortcuts import render
from django.contrib.auth.views import LoginView


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)

Penjelasan Kode

  • Pertama kita mengimport class View dan juga method render. Kedua nya akan kita gunakan untuk membuat HomeView.
  • kedua kita membuat class View baru yaitu HomeView yang mana di dalamnya kita tambahkan method get untuk merender atau menampilkan halaman dari file accounts/home.html.

Selanjutnya buat file baru home.html di dalam folder django_login_register/myauth/accounts/home.html dan tuliskan kode seperti di bawah ini.

<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="#" 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">
    <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>
</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

  • pada template home ini hanya sebuah halaman html biasa, kecuali di bagian berikut yang digunakan untuk menampilkan username dari user yang login. Django menyimpan info user yang login seperti username, email, firstname dll di dalam object user.

    <h4 class="card-title mt-2">{{ user.username }}</h4>
    

Terakhir kita tambahkan url untuk halaman home. Buka file django_login_register/myauth/urls.py dan ubah seperti di bawah ini.

from django.urls import path

# import class View
from .views import CustomLoginView, HomeView

urlpatterns = [
    path('login/', CustomLoginView.as_view(), name='login'),
    path('home/', HomeView.as_view(), name='home'),
]

Penjelasan Kode

  • Pertama kita mengimport class HomeView dari file django_login_register/myauth/views.py

    from .views import CustomLoginView, HomeView
    
  • kemudian kita menambahkan route untuk halaman home.

    path('home/', HomeView.as_view(), name='home'),
    

Oke sekarang kita coba lagi untuk login menggunakan username dan password yang benar. Ketika sukses maka itu akan diredirect ke halaman home.

Halaman Home

Membuat FItur Logout

Fitur login sudah kita buat dan tentunya kita perlu membuat fitur logout pada aplikasi kita. Oke langsung saja untuk membuat fitur logout kita perlu mengkostumisasi View Logout bawaan Django. Buka file django_login_register/myauth/views.py . Sesuaikan kodenya seperti berikut.

from django.views import View
from django.shortcuts import render
from django.contrib.auth.views import LoginView, LogoutView


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'

Penjelasan Kode

  • Pertama kita menambahkan kode untuk mengimport class LogoutView yang merupakan view untuk fitur logout bawaan dari Django.

    from django.contrib.auth.views import LoginView, LogoutView
    
  • Selanjutnya kita membuat class CustomLogoutView yang merupakan turunan dari class LogoutView karena kita ingin melakukan kostumisasi. Kita ubah template_name yang digunakan (defaultnya registration/logout.html). Di sini kita menggunakan template login karena kita tidak akan membuat halaman khusus untuk logout. terakhir kita mengeset attribute next_page dengan value login. Attribute tersebut digunakan untuk menentukan url yang akan dituju setelah proses logout berhasil dan kita mengesetnya ke url login.

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

Selanjutnya kita akan menambahkan url untuk fitur logout. Buka file django_login_register/myauth/urls.py dan sesuaikan kodenya seperti berikut.

from django.urls import path

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

urlpatterns = [
    path('login/', CustomLoginView.as_view(), name='login'),
    path('home/', HomeView.as_view(), name='home'),
    path('logout/', CustomLogoutView.as_view(), name='logout')
]

Penjelasan Kode

  • Pertama kita menambahkan kode untuk mengimport class CustomLogoutView dari file django_login_register/myauth/views.py.

    from .views import CustomLoginView, HomeView, CustomLogoutView
    
  • Kemudian kita menambahkan kode untuk membuat url logout.

    urlpatterns = [
        ...
        path('logout/', CustomLogoutView.as_view(), name='logout')
    ]
    

Dan langkah terakhir kita perlu mengubah url pada tombol logout di halaman home. Buka file django_login_register/myauth/templates/accounts/home.html.

Ubah bagian berikut.

<a href="#" class="float-right btn btn-outline-primary mt-1">Log out</a>

Menjadi seperti kode di bawah ini.

<a href="{% url 'logout' %}" class="float-right btn btn-outline-primary mt-1">Log out</a>

Penjelasan Kode

  • Kita merender url logout dengan bantuan helper atau function dari Django yaitu function url diikuti dengan nama urlnya yaitu logout. itu nantinya akan secara otomatis menggenerate full url nya seperti ini: http://127.0.0.1:8000/logout/.

Fitur logout sudah selesai kita buat. Kamu bisa mengetesnya dengan melakukan login kemudian dari halaman home klik tombol logout. Jika berhasil maka akan dialihkan kembali ke halaman login.

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

Ebook Python & Django cuma 99k

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