5 min read

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.