🏠 Home / Hub

🦄 Python 09 — Django Framework

← Python Menu · ← Prev: CLI Project

Requirements: Python 01–08 ပြီးဖို့ လိုတယ်။ Django က Python OOP concept တွေနဲ့ built ဖြစ်တာမို့ class, inheritance, import တွေကိုနားလည်ဖို့ကောင်းတယ်။

1. Django ဆိုတာ

Django က Python မှာ အသုံးအများဆုံး full-stack web framework ပါ။ "Batteries included" philosophy — ORM, admin panel, auth, forms, templating, CSRF protection, migrations တွေ built-in ပါတယ်။

FeatureDjangoFlaskFastAPI
TypeFull-stack frameworkMicro frameworkAPI framework
ORMBuilt-in (Django ORM)Plugin (SQLAlchemy)Plugin (SQLAlchemy/Tortoise)
Admin panel✅ Auto-generated❌ Manual❌ Manual
TemplatingDTL (Django Template)Jinja2No template engine
Best forFull web apps, CMS, REST+HTMLSimple apps, prototypesHigh-performance APIs

2. Setup & New Project

# virtual environment အရင်ဆောက်
python -m venv venv
source venv/bin/activate       # Mac/Linux
venv\Scripts\activate           # Windows

# Django install
pip install django

# New project create
django-admin startproject mysite .
# (dot ထည့်ရင် current dir ထဲ, မထည့်ရင် subfolder ဆောက်)

# Development server start
python manage.py runserver
# http://127.0.0.1:8000 မှာ "The install worked!" မြင်ရမယ်

Project Structure

mysite/
├── manage.py           ← CLI entry point (runserver, migrate, etc.)
├── mysite/
│   ├── settings.py     ← all configuration
│   ├── urls.py         ← URL routing (main)
│   ├── wsgi.py         ← production server entry
│   └── asgi.py         ← async server entry
└── db.sqlite3          ← default SQLite database (auto-created)

3. App တည်ဆောက်ခြင်း

Django project = multiple apps. App တစ်ခုက feature set တစ်ခု (blog, shop, users).

# New app create
python manage.py startapp blog

# settings.py မှာ register လုပ်ရမယ်
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    ...
    'blog',   # ← ထည့်ပါ
]

App Structure

blog/
├── models.py       ← database models (ORM)
├── views.py        ← request handlers
├── urls.py         ← URL patterns (app-level)
├── admin.py        ← admin registration
├── forms.py        ← form classes
├── templates/      ← HTML templates
│   └── blog/
│       ├── list.html
│       └── detail.html
└── migrations/     ← database migration files

4. Models & Database ORM

# blog/models.py
from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    title   = models.CharField(max_length=200)
    content = models.TextField()
    author  = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    published = models.BooleanField(default=False)

    class Meta:
        ordering = ['-created']   # newest first

    def __str__(self):
        return self.title
# migrations run
python manage.py makemigrations blog   # migration file ဆောက်
python manage.py migrate               # database ကို apply

# Django Shell မှာ data test
python manage.py shell
>>> from blog.models import Post
>>> Post.objects.create(title="First Post", content="Hello!", author_id=1, published=True)
>>> Post.objects.all()
>>> Post.objects.filter(published=True)
>>> Post.objects.filter(title__contains="First")  # field lookups
>>> Post.objects.get(id=1)
>>> Post.objects.order_by('-created')[:5]          # top 5 newest

Relationships

# One-to-Many (ForeignKey)
author = models.ForeignKey(User, on_delete=models.CASCADE)

# Many-to-Many
tags = models.ManyToManyField('Tag', blank=True)

# One-to-One
profile = models.OneToOneField(User, on_delete=models.CASCADE)

# Cascade options
on_delete=models.CASCADE       # parent delete → child delete
on_delete=models.SET_NULL      # parent delete → child.fk = NULL
on_delete=models.PROTECT       # prevent parent delete if children exist

5. Views & URLs

Function-based Views (FBV)

# blog/views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post

def post_list(request):
    posts = Post.objects.filter(published=True)
    return render(request, 'blog/list.html', {'posts': posts})

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/detail.html', {'post': post})

def post_create(request):
    if request.method == 'POST':
        title   = request.POST.get('title')
        content = request.POST.get('content')
        Post.objects.create(title=title, content=content,
                            author=request.user, published=True)
        return redirect('post_list')
    return render(request, 'blog/form.html')

URL Patterns

# blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('',        views.post_list,   name='post_list'),
    path('<int:pk>/', views.post_detail, name='post_detail'),
    path('new/',    views.post_create,  name='post_create'),
]

# mysite/urls.py (main)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/',  include('blog.urls')),
    path('',       include('blog.urls')),
]

6. Templates (Django Template Language)

{# blog/templates/blog/list.html #}
<!DOCTYPE html>
<html>
<head><title>Blog</title></head>
<body>
  <h1>Blog Posts</h1>
  {% for post in posts %}
    <div>
      <h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></h2>
      <p>{{ post.created|date:"Y-m-d" }}</p>
      <p>{{ post.content|truncatewords:30 }}</p>
    </div>
  {% empty %}
    <p>No posts yet.</p>
  {% endfor %}
</body>
</html>

Template Inheritance

{# templates/base.html #}
<!DOCTYPE html>
<html>
<head>
  <title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
  <nav><a href="/">Home</a></nav>
  {% block content %}{% endblock %}
</body>
</html>

{# blog/list.html extends base #}
{% extends "base.html" %}
{% block title %}Blog{% endblock %}
{% block content %}
  {% for post in posts %}...{% endfor %}
{% endblock %}
Template Tag/FilterDescription
{{ variable }}Output variable
{% for x in list %}Loop
{% if condition %}Conditional
{% url 'name' %}Reverse URL lookup
{% extends "base.html" %}Template inheritance
{% block name %}Define replaceable block
{% csrf_token %}CSRF protection for forms
{{ text|truncatewords:20 }}Shorten text
{{ date|date:"d M Y" }}Format date
{{ text|linebreaks }}Newlines → <br>

7. Forms & Validation

# blog/forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model  = Post
        fields = ['title', 'content', 'published']
        widgets = {
            'content': forms.Textarea(attrs={'rows': 8}),
        }

# blog/views.py
def post_create(request):
    form = PostForm(request.POST or None)
    if form.is_valid():
        post = form.save(commit=False)
        post.author = request.user
        post.save()
        return redirect('post_list')
    return render(request, 'blog/form.html', {'form': form})

{# form.html template #}
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Save</button>
</form>

8. Admin Panel

# blog/admin.py
from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ['title', 'author', 'created', 'published']
    list_filter  = ['published', 'created']
    search_fields = ['title', 'content']
    list_editable = ['published']   # edit published directly in list

# Superuser ဆောက်
python manage.py createsuperuser

# http://127.0.0.1:8000/admin/ မှာ login ဝင်ပြီး data manage လုပ်နိုင်

9. REST API (Django REST Framework)

pip install djangorestframework

# settings.py
INSTALLED_APPS += ['rest_framework']

# blog/serializers.py
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model  = Post
        fields = ['id', 'title', 'content', 'created', 'published']

# blog/views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.filter(published=True)
    serializer_class = PostSerializer

# blog/urls.py
from rest_framework.routers import DefaultRouter
from .views import PostViewSet

router = DefaultRouter()
router.register('posts', PostViewSet)

urlpatterns = router.urls
# GET  /api/posts/       → list
# POST /api/posts/       → create
# GET  /api/posts/1/     → detail
# PUT  /api/posts/1/     → update
# DELETE /api/posts/1/  → delete

10. Static Files & Settings

# settings.py key settings
DEBUG = True   # production မှာ False ထားမယ်

ALLOWED_HOSTS = ['localhost', '127.0.0.1']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

# PostgreSQL switch
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydb',
        'USER': 'postgres',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

STATIC_URL = '/static/'
MEDIA_URL  = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

LOGIN_URL     = '/accounts/login/'
LOGIN_REDIRECT_URL = '/'

11. Artisan → Manage.py Command Reference

CommandDescription
python manage.py runserverDev server start
python manage.py startapp nameNew app create
python manage.py makemigrationsDetect model changes
python manage.py migrateApply migrations to DB
python manage.py createsuperuserCreate admin user
python manage.py shellPython shell with Django
python manage.py collectstaticGather static files (production)
python manage.py testRun tests
python manage.py dumpdataExport data to JSON
python manage.py loaddataImport JSON data

🎉 Django Lesson Complete!

Django → Full-stack web apps, content sites, REST APIs, admin panels

Models Views Templates ORM Admin DRF migrations

📌 Study Checklist