Panduan praktis dan terstruktur mengenai panduan lengkap: membuat halaman login dengan django dan boostrap 4 berstandar enterprise. Pelajari konsep, implementasi kode modern, dan tips arsitektur enterprise siap produksi.
Selamat datang di seri tutorial engineering SiHubung! Pada artikel ini, kita akan membedah secara komprehensif implementasi Panduan Lengkap: Membuat Halaman Login Dengan Django Dan Boostrap 4 Berstandar Enterprise dengan standar kode bersih (clean code), performa tinggi, dan arsitektur siap produksi.

Membangun aplikasi web di era modern memerlukan pondasi yang kokoh. Framework modern memberikan fleksibilitas luar biasa bagi developer untuk menghadirkan fitur kompleks secara cepat tanpa mengabaikan aspek keamanan dan keandalan sistem.

Tahapan Implementasi & Walkthrough Kode

Berikut adalah langkah demi langkah teknis yang dapat Anda ikuti langsung pada codebase Anda:

Tahap 1: Penulisan Kode & Konfigurasi

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

Tahap 2: Penulisan Kode & Konfigurasi

cd django_login_register

Tahap 3: Penulisan Kode & Konfigurasi

python -m venv .env

Tahap 4: Penulisan Kode & Konfigurasi

source .env/bin/activate

Tahap 5: Penulisan Kode & Konfigurasi

Django
django-widget-tweaks

Tahap 6: Penulisan Kode & Konfigurasi

pip install -r requirements.txt

Tahap 7: Penulisan Kode & Konfigurasi

./manage.py migrate

Tahap 8: Penulisan Kode & Konfigurasi

./manage.py runserver

Tahap 9: Penulisan Kode & Konfigurasi

(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.

Tahap 10: Penulisan Kode & Konfigurasi

django-admin startapp myauth

Tahap 11: Penulisan Kode & Konfigurasi

├── 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

Tahap 12: Penulisan Kode & Konfigurasi

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'
]

Tahap 13: Penulisan Kode & Konfigurasi

from django.contrib.auth.views import LoginView


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

Tahap 14: Penulisan Kode & Konfigurasi

from django.contrib.auth.views import LoginView

Tahap 15: Penulisan Kode & Konfigurasi

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

Tahap 16: Penulisan Kode & Konfigurasi

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

Tahap 17: Penulisan Kode & Konfigurasi

<div>
    {% if form.errors %}
    <div class="alert alert-danger">
        Username atau Password kamu salah. Silahkan coba kembali.
    </div>
    {% endif %}
</div>

Tahap 18: Penulisan Kode & Konfigurasi

{% 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>

Tahap 19: Penulisan Kode & Konfigurasi

from django.urls import path

# import class View
from .views import CustomLoginView

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

Tahap 20: Penulisan Kode & Konfigurasi

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

Tahap 21: Penulisan Kode & Konfigurasi

from django.urls.conf import include

Tahap 22: Penulisan Kode & Konfigurasi

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

Tahap 23: Penulisan Kode & Konfigurasi

./manage.py createsuperuser

Tahap 24: Penulisan Kode & Konfigurasi

(.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$

Tahap 25: Penulisan Kode & Konfigurasi

LOGIN_REDIRECT_URL = 'home'

Tahap 26: Penulisan Kode & Konfigurasi

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)

Tahap 27: Penulisan Kode & Konfigurasi

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

Tahap 28: Penulisan Kode & Konfigurasi

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

Tahap 29: Penulisan Kode & Konfigurasi

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'),
]

Tahap 30: Penulisan Kode & Konfigurasi

from .views import CustomLoginView, HomeView

Tahap 31: Penulisan Kode & Konfigurasi

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

Tahap 32: Penulisan Kode & Konfigurasi

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'

Tahap 33: Penulisan Kode & Konfigurasi

from django.contrib.auth.views import LoginView, LogoutView

Tahap 34: Penulisan Kode & Konfigurasi

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

Tahap 35: Penulisan Kode & Konfigurasi

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')
]

Tahap 36: Penulisan Kode & Konfigurasi

from .views import CustomLoginView, HomeView, CustomLogoutView

Tahap 37: Penulisan Kode & Konfigurasi

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

Tahap 38: Penulisan Kode & Konfigurasi

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

Tahap 39: Penulisan Kode & Konfigurasi

<a href="{% url 'logout' %}" class="float-right btn btn-outline-primary mt-1">Log out</a>
💡 Tips Rekayasa Perangkat Lunak (SiHubung Engineering Best Practice)

Selalu gunakan pendekatan deklaratif, validasi input seawal mungkin di boundary layer, dan lakukan logging terstruktur untuk memudahkan observability ketika sistem dijalankan di lingkungan cloud produksi.

Kesimpulan

Dengan mengikuti langkah-langkah terstruktur di atas, implementasi modul Anda akan jauh lebih rapi, aman dari bug umum, serta siap diskalakan ke lingkungan produksi.

Nantikan artikel tutorial praktis lainnya seputar fullstack development, microservices, dan otomasi AI di Blog Engineering SiHubung. Selamat mencoba!