Django projek: Membuat cms blog
Di tulisan django kemarin setidaknya sudah tiga hal yang bisa kita mulai membuat aplikasi berbasis django, di tulisan ini saya akan rekap ke 3 tulisan tadi, hingga di akhir tulisan kita akan membuat satu buah aplikasi web, tulisan ini akan berfokus di:
- Install django
- Setup django project
- Create django app
- Mode dan Migration
Note: Salah satu rekomendasi dalam membuat aplikasi python adalah menggunakan virtual env, tapi kita bahas itu nanti, fokus di seri ini lebih ke membuat aplikasi django. Salah satu rekomendasi saya menggunakan pipenv
Di rekap kali ini kita akan membuat sebuah cms untuk blog, di mana hasil akhirnya nanti kita punya satu cms untuk mengelola blog sendiri.
Install django
Untuk instal django itu seperti memasang package python lainnya menggunakan pip
pip install django
Setup django project
Kita bisa langsung membuat django project ketika sudah memasang django dengan cara
django-admin startproject cms
atau jika seperti saya sudah menyiapakan satu folder kosong untuk menampung projek django maka seperti ini
mkdir projek-django cd projek-django django-admin startproject cms .
isi dari projek kita akan sebagai berikut
├── cms │ ├── asgi.py │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py
Running django project
Untuk menjalankan kita kan menggunakan django command yaitu runserver, jalankan perintah ini
python manage.py runserver
Fungsi di atas ini menjalankan project django di port 8000 secara default, ingat fungsi di atas hanya dijalankan di mode development saja tidak rekomendasi dijalankan di mode prodcutions.
Saat kita akses di browser maka akan terlihat
Setelah menjalankan perintah di atas di terminal akan melihat seperti ini
Jangan takut atau khawatir dengan warning tersebut, warning di sana memberitahu bahawa kita belum memasang tabel-tabel default django yang berguna.
Note: Seperti di tulisan awal django datang dengan banyak fitur bawaan seperti auth, acl, admin dashboard dll. Warning di atas adalah kebutuhan untuk prasyarat fitur-fitur yang tadi disebut. Secara default django akan menggunakan database sqlite, untuk development kita akan menggunakan sqlite juga
Untuk menghilangkan warning itu cukup ketikan
python manage.py migrate
Create django app
Mari buat blog, kita buat blog menggunakan django. Oleh karena itu mari kita buat rencananya lebih dulu:
- Kita akan membuat blog, oleh karena kita buat app namanya blog
- Dalam blog nanti kita akan memiliki model
- Category
- Tags
- Content
Untuk membuat app kita gunakan perintah
python manage.py startapp blog
Perintah di atas akan menghasilkan satu folder app blog, sehingga sekarang folder kita strukturnya seperti ini
├── blog │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── cms │ ├── asgi.py │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── db.sqlite3 ├── manage.py
Mari membuat kebutuhan blog dengan membuat model yang nantinya akan menjadi tabel, buat model seperti ini
from django.db import models # Create your models here. class Category(models.Model): name = models.CharField(max_length=50) slug = models.CharField(max_length=100, null=True) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Tags(models.Model): name = models.CharField(max_length=50) slug = models.CharField(max_length=100, null=True) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Content(models.Model): title = models.CharField(max_length=100) slug = models.CharField(max_length=200, null=True) category = models.ForeignKey( Category, related_name="content", on_delete=models.CASCADE ) tags = models.ManyToManyField(Tags, related_name="content") body = models.TextField() publish = models.BooleanField(default=False) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) def __str__(self): return self.title
Daftarkan app blog kita di settings, buka berkas “cms/settings.py” lalu tambahkan blog di list instaled_apps
INSTALLED_APPS = [ #default django app "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", #our app "blog", ]
Lalu buat migration untuk app blog kita
python manage.py makemigrations blog
Saat menjalankan perintah itu maka akan muncul di terminal model mana saja yang dibuatkan migration filenya
Migrations for 'blog': blog/migrations/0001_initial.py - Create model Category - Create model Tags - Create model Content
lalu kita tengok berkas migration yang dibuat, lokasinya ada di folder migrations di app blog
# Generated by Django 3.2.9 on 2021-12-14 14:06 from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=50)), ('slug', models.CharField(max_length=100, null=True)), ('date_created', models.DateTimeField(auto_now_add=True)), ('date_updated', models.DateTimeField(auto_now=True)), ], ), migrations.CreateModel( name='Tags', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=50)), ('slug', models.CharField(max_length=100, null=True)), ('date_created', models.DateTimeField(auto_now_add=True)), ('date_updated', models.DateTimeField(auto_now=True)), ], ), migrations.CreateModel( name='Content', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=100)), ('slug', models.CharField(max_length=200, null=True)), ('body', models.TextField()), ('publish', models.BooleanField(default=False)), ('date_created', models.DateTimeField(auto_now_add=True)), ('date_updated', models.DateTimeField(auto_now=True)), ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='content', to='blog.category')), ('tags', models.ManyToManyField(related_name='content', to='blog.Tags')), ], ), ]
Itu adalah “default” kita membuat model, tapi kadangkala kita ingin saat migration itu kita juga import initial data, mari kita buat migration untuk initial datanya
python manage.py makemigrations --empty blog
perhatikan parameter –empty di sana, di sana mengartikan bahwa kita akan membuat satu file migration tapi tanpa mengubah atau menambah struktur sebuah tabel, kalau kita lihat di berkas migration “kedua” (di komputer saya migration kedua ada dengan nama 0002_auto_20211214_1414.py) isinya hanya seperti berikut
# Generated by Django 3.2.9 on 2021-12-14 14:14 from django.db import migrations class Migration(migrations.Migration): dependencies = [ ('blog', '0001_initial'), ] operations = [ ]
Sepi bukan? hanya ada “dependencies” yang maksudnya sebelum running migration yang ini akan menjalankan atau memastikan si initial itu udah ada, dan ada “operations”.
Untuk initialnya kita bisa menggunakan orm django (untuk orm kita bahas terpisah), mari ubah migration ini jadi seperti ini
# Generated by Django 3.2.9 on 2021-12-14 14:14 from django.db import migrations def default_data_for_category(apps, schema_editor): # We can't import the model directly as it may be a newer # version than this migration expects. We use the historical version. Category = apps.get_model("blog", "Category") data = [ {"name": "Default", "slug": "default"}, {"name": "Daily", "slug": "daily"}, {"name": "Tech", "slug": "tech"}, ] for d in data: c = Category(**d) c.save() class Migration(migrations.Migration): dependencies = [("blog", "0001_initial")] operations = [migrations.RunPython(default_data_for_category)]
Untuk menjalankannya
python manage.py migrate blog
hasilnya akan muncul informasi berikut
Applying blog.0001_initial... OK Applying blog.0002_auto_20211214_1414... OK
Mari kita lihat di database, apakah benar tabelnya terbentuk dan data initialnya ikut terpasang.
dan datanya
Oke setup selesai, di tulisan berikutnya akan berfokus di bagian yang menurut saya menyenangkan: Orm, Admin, dan Forms. Sampai jumpa.