Setelah sekian lama terlalu malas untuk menulis dikarenakan tasks yang menumpuk, akhirnya saya niatkan untuk membuat tutorial lanjutan Django Framework.
Jika sebelumnya kita telah mempelajari tentang implementasi sebuah template pada django, kali ini kita akan mempelajari tentang cara membuat user login, register dan logout pada django.
Ada 3 cara untuk membuat sebuah authentication pada framework django tanpa menggunakan third party (packages).
User
. (Yang akan kita gunakan pada tutorial kali ini)AbstractUser
.AbstractBaseUser
.User
DjangoPada tutorial kali ini, kita menggunakan latest django version. Yaitu Django-4.*
Langsung saja kita mulai.
Saya asumsikan kita semua telah menginstall Virtual Environment yang akan kita gunakan pada tutorial kali ini. Jika kita belum mengetahui apa itu Virtual Environment, maka sebaiknya kita mempelajarinya terlebih dahulu, karena Virtual Environment sangatlah penting ketika kita menjalan sebuah project yang menggunakan bahasa pemrograman Python.
Bukalah terminal / cmd kesayangan kita, dan ketikkan perintah seperti di bawah ini:
# membuat directory dengan nama starter, nama root directory kita.
$ mkdir starter
# masuk ke dalam directory tersebut
$ cd starter
# install django menggunakan pip
$ pip install django
Collecting django
Downloading Django-3.1.3-py3-none-any.whl (7.8 MB)
|████████████████████████████████| 7.8 MB 1.9 MB/s
Collecting pytz
Downloading pytz-2020.4-py2.py3-none-any.whl (509 kB)
|████████████████████████████████| 509 kB 2.6 MB/s
Collecting asgiref<4,>=3.2.10
Downloading asgiref-3.3.0-py3-none-any.whl (19 kB)
Collecting sqlparse>=0.2.2
Using cached sqlparse-0.4.1-py3-none-any.whl (42 kB)
Installing collected packages: pytz, asgiref, sqlparse, django
Successfully installed asgiref-3.3.0 django-3.1.3 pytz-2020.4 sqlparse-0.4.1
Django telah sukses terinstall, now let’s get into it!
# membuat project bernama 'core'
$ django-admin startproject core
# membuat app bernama 'accounts'
$ ./manage.py startapp accounts
core
.accounts
.Langkah selanjutnya adalah update file settings.py
kita yang berada di dalam folder project core
.
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# nama app yang telah kita buat sebelumnya
'accounts.apps.AccountsConfig',
]
# menyiapkan migrations untuk pembuatan database table dsb.
$ ./manage.py makemigrations
# menjalakan migrations yang telah dibuat sebelumnya
$ ./manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
...
...
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
Setelah berhasil melakukan makemigrations
& migrate
, langkah selanjutnya adalah membuat sebuah user / superuser untuk masuk ke django admin dashboard dengan menggunakan command:
# membuat superuser / root untuk project kita
$ ./manage.py createsuperuser
Username (leave blank to use 'icoldplayer'): admin # nama username kita
Email address:
Password:
Password (again):
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
Pada perintah di atas, kita telah berhasil membuat superuser bernama username: admin
yang akan kita gunakan untuk masuk ke django dashboard setelah ini.
Jika perintah sebelumnya sukses, maka kita bisa menjalankan django server:
$ ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
November 07, 2020 - 16:09:37
Django version 3.1.3, using settings 'core.settings'
Starting development server at http://127.0.0.1:3000/
Quit the server with CONTROL-C.
Bukalah url tersebut http://127.0.0.1:8000/
atau localhost:8000
pada browser kesayangan kita, maka kita akan mendapatkan landing page default django.
Selanjutnya, masuklah ke django dashboard localhost:8000/admin/
, gunakan credentials yang sebelumnya telah kita buat, maka kita telah berhasil masuk ke dashboard seperti di bawah ini:
Pada gambar sebelumnya di atas, kita berhasil masuk ke dashboard admin, langkah selanjutnya kita akan membuat sebuah models
pada app accounts
yang sebelumnya kita buat.
accounts/models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils.timezone import now
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
my_photo = models.ImageField(default='pp.png', upload_to='dp/')
first_name = models.CharField(blank=True, max_length=20)
last_name = models.CharField(blank=True, max_length=20)
email = models.CharField(blank=False, null=False, max_length=100)
phone = models.CharField(blank=True, null=True, max_length=14)
joined = models.DateTimeField(default=now, editable=False)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
from django.contrib.auth.models import User
kita menggunakan default User
pada django.class Profile
, kita menggunakan relation OneToOneField
, dengan tujuan ketika kita menghapus sebuah user object
pada model Users
, maka user object
tersebut juga akan terhapus dari model class profile
. Sehingga kita tidak berungkali mengahapus satu persatu dari semua model yang ada.Langkah selanjutnya, jangan lupa untuk menjalankan makemigrations
dan migrate
$ ./manage.py makemigrations
Migrations for 'accounts':
accounts/migrations/0001_initial.py
- Create model Profile
$ ./manage.py migrate
Operations to perform:
Apply all migrations: accounts, admin, auth, contenttypes, sessions
Running migrations:
Applying accounts.0001_initial... OK
Daftarkan terlebih dahulu Profile
model tersebut ke django admin dengan cara:
from django.contrib import admin
from accounts.models import Profile
class ProfileAdmin(admin.ModelAdmin):
pass
admin.site.register(Profile, ProfileAdmin)
Jalankan kembali server ./manage.py runserver
dan masuk ke dashboard admin, maka model Profile
kita telah terdaftar di sana.
Dari segi backend, aplikasi kita di atas telah siap untuk digunakan, kita dapat langsung menambahkan user melalui django admin.
Seperti yang kita lihat, pada gambar tersebut kita dapat langsung menambakan user dengan username “userbaru” melalui django admin.
Selanjutkan kita akan membuat views
, forms
dan signals
yang berfungsi untuk mengirimkan data ketika user / visitor melalukan pendaftaran dari sisi frontend.
Membuat forms
yang digunakan untuk user input saat pendaftaran.
Buatlah sebuah file baru di dalam directory accounts
bernama forms.py
seperti di bawah ini:
Buatlah kode seperti di bawah ini dalam directory accounts/forms.py
kita.
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class SignUpForm(UserCreationForm):
username = forms.CharField(
label='<b>Username</b>',
help_text='<b>Username digunakan pada saat login</b>'
)
email = forms.EmailField(
label='<b>Email</b>',
max_length=100,
help_text='<b>Gunakan email bisnis anda.</b>'
)
password1 = forms.CharField(
label='<b>Password</b>',
strip=False,
widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
help_text='<b>Use Secure Password!</b>'
)
password2 = forms.CharField(
label='<b>Konfirmasi Password</b>',
strip=False,
widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
help_text='<b>Samakan dengan password di atas</b>',
)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2',)
forms
di atas, kita menggunakan registration default form dari django yaitu UserCreationForm
.label
guna memberikan kesan user experience yang lebih baik.Selanjutnya adalah, membuat sebuah function
pada views
yang akan digunakan untuk meng-handle data yang diterima dari form di atas ketika user melakukan submit data pada form register nantinya.
Source code untuk views dalam directory accounts/views.py
from django.shortcuts import render, redirect, HttpResponse
from django.contrib.auth.models import User
from django.contrib import messages
from .forms import SignUpForm, ProfileUpdateForm, UserUpdateForm
from accounts.models import Profile
def Register(request):
if request.method == "POST":
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Akun baru telah berhasil dibuat, dengan username: {username}!')
password = form.cleaned_data.get('password1')
return redirect("/")
else:
for msg in form.error_messages:
print(form.error_messages[msg])
return render(request=request,
template_name="accounts/auth/register.html",
context={"form": form})
form = SignUpForm
return render(request=request,
template_name="accounts/auth/register.html",
context={"form": form})
User
default pada django.views
di atas, kita mengimport / memanggil forms
dan Profile models
.Pada source code di atas, kita membuat sebuah function Register
yang menampung form yang telah kita buat sebelumnya yaitu SignUpForm
yang akan kita gunakan untuk mengolah data ketika user register.
Langkah selanjutnya kita akan membuat urls
yang akan digunakan untuk routing ketika user register, login, dan logout pada situs / aplikasi kita nantinya.
Buatlah file bernama urls.py
dalam directory accounts/urls.py
seperti di bawah ini:
from django.urls import path
from accounts import views as account_views
from django.contrib.auth import views as auth_views
urlpatterns = [
path('register/', account_views.Register, name='register'),
path('login/', auth_views.LoginView.as_view(template_name='accounts/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='accounts/logout.html'), name='logout'),
]
Pada source code di atas, kita membuat sebuah url routing untuk register, login, dan logout.
pada url register
, kita menggunakan function Register
yang telah dibuat sebelumnya pada views.py
.
Dan menggunakan default login authentication pada yang django miliki, yaitu LoginView
dan LogoutView
yang telah kita import sebelumnya melalui baris:
from django.contrib.auth import views as auth_views
Langkah selanjutnya adalah, kita melalukan update settings
dan urls
pada project kita (core
) agar menggunakan app account untuk user registrasi, login, dan logout.
Buka file settings.py
yang berada dalam filder core
dan masukkan beberapa baris kode berikut:
...
# update auth pada setting
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = 'login'
LOGIN_URL = 'login'
ACCOUNT_SIGNUP_FORM_CLASS = 'accounts.forms.SignUpForm'
WSGI_APPLICATION = 'core.wsgi.application'
# end
...
Pada baris kode di atas, kita memerintahkan django untuk menggunakan authentication
yang baru saja kita buat, untuk menghandle user register, login dan logout pada aplikasi kita.
LOGIN_REDIRECT_URL
adalah url redirect yang akan diterima oleh user ketika mereka berhasil login.LOGOUT_REDIRECT_URL
adalah kebalikan dari login, atau url redirect ketika mereka logout dari aplikasi / situs kita.ACCOUNT_SIGNUP_FORM_CLASS
adalah form register yang digunakan untuk registrasi user pada aplikasi kita.Update fiel urls.py
directory project kita core
seperti di bawah ini:
from django.contrib import admin
from django.urls import path, include
from accounts import views
urlpatterns = [
path('admin/', admin.site.urls),
# # url home kita
path('', views.home, name='home'),
# url account
path('', include('accounts.urls'))
]
Pada source di atas, kita mengimport app accounts
ke base url (core/urls.py
) project kita, agar base url tersebut dapat membaca url yang ada pada app accounts/urls.py
dengan menggunakan metode include
.
Langkan selanjutkan adalah membuat sebuah template dan memunculkannya pada bagian frontend sehingga dapat digunakan oleh siapa saja yang mengunjungi aplikasi kita.
Update kembali file settings.py
kita pada bagian template seperti di bawah ini:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# sebelumnya
# 'DIRS': [],
# sesudah
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Pada baris kode di atas, kita memberitahu django untuk merender template yang ada pada directory templates
yang akan kita buat selanjutnya.
Buatlah directory bernama templates
, kita akan menggunakan directory tersebut untuk meletakkan semua templates yang ada pada project kita.
Navbar templates/nav.html
<div>
<ul>
<li><a href="{% url 'home' %}">home</a></li>
{% if user.is_authenticated %}
<li><a href="{% url 'logout' %}">logout</a></li>
{% else %}
<li><a href="{% url 'register' %}">register</a></li>
<li><a href="{% url 'login' %}">login</a></li>
{% endif %}
</ul>
</div>
base template templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% include 'nav.html' %}
{% block content %}
<!-- content goes here -->
{% endblock %}
</body>
</html>
Register form template templates/accounts/register.html
:
{% extends 'base.html' %}
{% block content %}
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p | safe }}
<input type="submit" value="submit">
</form>
{% endblock %}
Home template templates/home.html
{% extends 'base.html' %}
{% block content %}
{% if user.is_authenticated %}
<h3>Anda telah berhasil login!</h3>
{% else %}
<h4>Anda belum login</h4>
{% endif %}
{% endblock %}
Login form template templates/accounts/login.html
:
{% extends 'base.html' %}
{% block content %}
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="login">
</form>
{% endblock %}
Setelah semua template tersebut terbuat, kini saatnya kita menjalankan aplikasi kita:
$ ./manage.py runserver
Dan jika kita mengjunngi halaman localhost:8000/home/
, maka kita akan mendapatkan tampilan seperti berikut:
Dan seperti yang kita lihat, tertera tulisan “Anda belum login”.
Langkah selanjutnya kita akan klik link register
tersebut untuk mencoba melakukan pendaftaran seperti di bawah ini:
Klik submit, maka kita akan diarahkan ke halaman login
, seperti di bawah ini:
Cobalah untuk login dengan username yang baru saja kita buat yaitu usernamebaru
seperti tertera di gambar, masukkan password, maka kita akan kembali ke halaman home dengan message yang berbeda.
Yep!. it works!
Kita telah berhasil login menggunakan username yang baru saya kita daftarkan, dan ketika kita pergi ke link logout, maka kitapun akan kembali diarahkan ke halaman login.
Cukup simple bukan?
Artikel ini sengaja saya buat sedetail mungkin agar mempermudah kita untuk mempelajari lebih dalam tentang bagaimana membuat sebuah user authentication pada django dengan menggunakan default User
model yang sudah ada (Built-in) User model.
Untuk artikel selanjutnya kita akan mencoba untuk membuat forgot password, reset password, dan profile update agar user dapat mengupdate data diri mereka pada aplikasi kita.
Untuk bagian tanya jawab, silahkan tinggalkan komentar teman-teman pada kolom komentar yang tersedia di bawah.
Source code juga dapat teman-teman download di sini: https://github.com/IamnoTnoob/resources/tree/master/django-auth
Terimakasih sudah terkunjung & keep learning!
Cheers!