Membuat project Django pertama dengan django-admin startproject dan startapp, membedah peran manage.py dan settings.py, memahami struktur folder project versus app, serta menjalankan development server dan memastikan respons HTTP pertama.

Setelah memahami arsitektur MTV di episode 2, sekarang saatnya hands-on: membuat project Django nyata pertama. Di episode ini kalian menjalankan django-admin startproject, membedah setiap file yang dihasilkan, menambahkan app pertama, dan menghidupkan development server — momen ketika teori MTV mulai terasa nyata di layar.
Mengapa episode ini penting? Karena struktur project yang benar sejak awal menentukan seberapa nyaman kalian menambahkan fitur di 23 episode berikutnya. manage.py, settings.py, dan pemisahan project-app adalah fondasi yang sama di semua project Django, dari proyek kecil sampai yang melayani jutaan request.
Pastikan venv episode 0 aktif, lalu buat project devblog:
cd ~/devblog
django-admin startproject devblog .Perhatikan titik . di akhir: Django akan membuat package devblog/ di dalam folder saat ini, bukan membuat folder devblog/devblog yang berlapis. Hasilnya:
devblog/
.venv/
manage.py
devblog/
__init__.py
asgi.py
settings.py
urls.py
wsgi.pyNote
django-admin dan manage.py sebenarnya script yang sama. manage.py hanya lebih pintar: ia otomatis membaca DJANGO_SETTINGS_MODULE dari project kalian. Karena itu kebiasaan baiknya adalah selalu python manage.py ... di dalam project, bukan django-admin ....
Script komando utama project. Semua operasi — runserver, makemigrations, migrate, startapp, createsuperuser — lewat sini. Isinya hampir tidak pernah diubah, hanya disetel ke devblog.settings secara default.
#!/usr/bin/env python
import os
import sys
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "devblog.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()os.environ.setdefault("DJANGO_SETTINGS_MODULE", "devblog.settings") adalah kunci: ia memberi tahu Django settings mana yang dipakai. Di episode 16 kita akan mengganti baris ini untuk mendukung banyak environment.
Jantung konfigurasi. Beberapa bagian paling penting:
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = "django-insecure-..." # diganti di episode 16
DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}BASE_DIR menjadi dasar semua path absolut project. INSTALLED_APPS menentukan aplikasi yang aktif — termasuk blog yang akan kita daftarkan sebentar lagi. DATABASES default memakai SQLite agar lab langsung jalan tanpa setup server.
urls.py adalah URLconf root — tempat urlpatterns pertama ditulis. asgi.py dan wsgi.py adalah entry point server produksi (ASGI untuk Channels/Uvicorn di episode 21 dan 23, WSGI untuk Gunicorn). Untuk sekarang, biarkan keduanya.
Sekarang buat app blog:
python manage.py startapp blogIni menghasilkan folder blog/ dengan models.py, views.py, admin.py, apps.py, tests.py, dan folder migrations/. App belum aktif sampai didaftarkan di INSTALLED_APPS:
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog", # app kita
]Mengapa harus didaftarkan? Karena Django hanya memproses migrasi, admin, template, dan signal dari app yang terdaftar. Lupa mendaftarkan app adalah penyebab klasik error No module named 'blog' atau tabel tidak terbuat.
Tip
Struktur lab yang ideal di akhir episode ini: devblog/ (config) dan blog/ (app) sebagai sibling, bukan blog di dalam devblog. Karena blog tidak bersarang, ia mudah di-pindah atau di-reuse ke project lain — persis semangat "app sebagai unit fungsional" dari episode 2.
Jalankan server bawaan:
python manage.py runserverBuka http://127.0.0.1:8000 — kalian akan melihat halaman roket Django. Output terminal menampilkan warning migrations yang belum dijalankan; itu normal dan akan kita bereskan di episode 7. Coba juga akses http://127.0.0.1:8000/admin untuk melihat panel admin bawaan.
Warning
runserver adalah server pengembangan, bukan server produksi. Ia menampilkan traceback penuh dan berjalan single-threaded — tidak cocok untuk traffic nyata. Produksi memakai Gunicorn/Uvicorn yang kita setup di episode 23. Jangan pernah menjalankan runserver di luar environment development.
Untuk verifikasi otomatis, kalian bisa menggunakan manage.py check yang memvalidasi konfigurasi tanpa server:
python manage.py check
python manage.py runserver 127.0.0.1:8000 --noreloadmanage.py check mencetak System check identified no issues jika semua konfigurasi valid — perintah yang sama dipakai pipeline CI/CD di episode 23.
Sebelum lanjut, inisialisasi git dan jangan pernah commit hal-hal berikut:
.venv/
__pycache__/
db.sqlite3
*.py[cod]
.envdb.sqlite3 dan .venv tidak boleh masuk repository — mereka environment-spesifik. Secret seperti SECRET_KEY juga harus dijauhkan dari git; kita pindahkan ke environment variable di episode 16.
Inti yang harus dibawa pulang:
django-admin startproject devblog . membuat project; startapp blog membuat app.manage.py adalah pintu semua perintah; settings.py adalah pusat konfigurasi.INSTALLED_APPS agar aktif.python manage.py runserver menghidupkan server development; check memvalidasi konfigurasi..gitignore sejak awal — jangan pernah commit venv, SQLite, atau secret.Di episode 4 selanjutnya kita masuk ke bagian pertama dari alur request: URL routing & views — menulis urlpatterns, path converters, name-based reverse, serta perbandingan Function-Based Views dan Class-Based Views dengan HttpResponse/JsonResponse. Pastikan runserver kalian masih menyala, karena kita mulai menulis respons nyata!