본문으로 건너뛰기 Django Complete Guide | MTV· ORM

Django Complete Guide | MTV· ORM

Django Complete Guide | MTV· ORM

이 글의 핵심

Django is Python's 'batteries included' web framework — used by Instagram, Pinterest, and Mozilla. This guide covers everything from project setup to production deployment, including the built-in Admin panel and Django REST Framework.

Why Django?

Django’s philosophy is “don’t repeat yourself” and “batteries included”. It ships with everything a web application needs:

  • ORM — write Python instead of SQL; automatic migrations
  • Admin panel — auto-generated CRUD interface from your models
  • Auth system — users, groups, permissions, sessions built in
  • Security — CSRF, XSS, SQL injection protection by default
  • REST Framework — best-in-class API layer (separate package)
Flask:   ~1,000 req/sec  (minimal, build everything yourself)
Django:  ~800  req/sec   (full-stack, batteries included)
FastAPI: ~3,000 req/sec  (API-only, async)

Installation & Project Setup

pip install django
django-admin startproject myproject
cd myproject
python manage.py runserver
# → http://localhost:8000

Create an app (Django organizes code into apps):

python manage.py startapp users

Register your app in settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    # ...
    'users',  # Your new app
]

Project structure:

myproject/
├── manage.py          # Command-line utility
├── myproject/
│   ├── settings.py    # Configuration
│   ├── urls.py        # Root URL configuration
│   └── wsgi.py        # WSGI entry point
└── users/
    ├── models.py      # Database models
    ├── views.py       # Request handlers
    ├── urls.py        # App URL patterns
    ├── admin.py       # Admin registration
    └── tests.py       # Unit tests

Models — Define Your Database Schema

Django models map directly to database tables. No SQL needed.

# users/models.py
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    age = models.IntegerField(null=True, blank=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_at']  # Newest first by default

    def __str__(self):
        return self.name

Apply the schema to your database:

python manage.py makemigrations   # Generate migration files
python manage.py migrate          # Apply to the database

ORM Queries

# Create
user = User.objects.create(name="Alice", email="alice@example.com")

# Read
all_users = User.objects.all()
active_users = User.objects.filter(is_active=True)
alice = User.objects.get(email="alice@example.com")  # Raises if not found

# Update
User.objects.filter(id=1).update(is_active=False)

# Delete
User.objects.filter(is_active=False).delete()

# Chaining
recent_active = (
    User.objects
    .filter(is_active=True)
    .order_by('-created_at')
    [:10]  # SQL LIMIT 10
)

Views — Handle HTTP Requests

Function-Based Views (FBV)

# users/views.py
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from .models import User

@require_http_methods(["GET"])
def user_list(request):
    users = User.objects.all().values('id', 'name', 'email')
    return JsonResponse(list(users), safe=False)

@require_http_methods(["GET"])
def user_detail(request, user_id):
    try:
        user = User.objects.get(id=user_id)
        return JsonResponse({
            'id': user.id,
            'name': user.name,
            'email': user.email,
        })
    except User.DoesNotExist:
        return JsonResponse({'error': 'User not found'}, status=404)

Class-Based Views (CBV)

Django’s generic CBVs reduce boilerplate for common patterns:

from django.views.generic import ListView, DetailView, CreateView
from django.urls import reverse_lazy

class UserListView(ListView):
    model = User
    template_name = 'users/list.html'
    context_object_name = 'users'
    paginate_by = 10                        # Auto-pagination

class UserDetailView(DetailView):
    model = User
    template_name = 'users/detail.html'
    context_object_name = 'user'

class UserCreateView(CreateView):
    model = User
    fields = ['name', 'email', 'age']
    success_url = reverse_lazy('user_list')  # Redirect after creation

URL Configuration

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

urlpatterns = [
    path('', views.user_list, name='user_list'),
    path('<int:user_id>/', views.user_detail, name='user_detail'),
]

Include app URLs in the root configuration:

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

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

Django REST Framework (DRF)

DRF is the standard way to build REST APIs with Django. Install it:

pip install djangorestframework

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'users',
]

Serializer — JSON ↔ Python Object Conversion

# users/serializers.py
from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'name', 'email', 'age', 'is_active', 'created_at']
        read_only_fields = ['id', 'created_at']

ViewSet — CRUD in One Class

A ModelViewSet automatically provides list, create, retrieve, update, and destroy endpoints:

# users/views.py
from rest_framework import viewsets, permissions
from .models import User
from .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        # Optional: filter by query param (?active=true)
        qs = super().get_queryset()
        if self.request.query_params.get('active'):
            qs = qs.filter(is_active=True)
        return qs

Router — Auto-Generate URLs

# users/urls.py
from rest_framework.routers import DefaultRouter
from .views import UserViewSet

router = DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = router.urls
# Generates:
# GET/POST   /users/
# GET/PUT/PATCH/DELETE /users/{id}/

Admin Panel

Django’s admin panel is auto-generated from your models. Customize it:

# users/admin.py
from django.contrib import admin
from .models import User

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'email', 'is_active', 'created_at']
    list_filter = ['is_active', 'created_at']
    search_fields = ['name', 'email']
    ordering = ['-created_at']
    list_per_page = 25
    readonly_fields = ['created_at', 'updated_at']

Create a superuser and log in:

python manage.py createsuperuser
# → http://localhost:8000/admin

The admin panel gives your team a full CRUD interface with search, filtering, and pagination — zero frontend code required.


Authentication

Built-in Session Auth

from django.contrib.auth.decorators import login_required

@login_required  # Redirects to /login/ if not authenticated
def protected_view(request):
    return JsonResponse({'user': request.user.username})

JWT Authentication (for APIs)

pip install djangorestframework-simplejwt

Configure DRF to use JWT:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}

Add token endpoints:

# urls.py
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view()),         # POST → access + refresh tokens
    path('api/token/refresh/', TokenRefreshView.as_view()),    # POST → new access token
]

Usage:

# Get tokens
curl -X POST http://localhost:8000/api/token/ \
  -d '{"username": "alice", "password": "secret"}'
# → {"access": "eyJ...", "refresh": "eyJ..."}

# Use the access token
curl http://localhost:8000/api/users/ \
  -H "Authorization: Bearer eyJ..."

Deployment

Gunicorn (Production WSGI Server)

pip install gunicorn
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000 --workers 4

Docker

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

# Collect static files
RUN python manage.py collectstatic --noinput

EXPOSE 8000

CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]

Production Settings Checklist

# settings_production.py
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com']
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST': os.environ['DB_HOST'],
    }
}
STATIC_ROOT = '/var/www/static/'
SECRET_KEY = os.environ['SECRET_KEY']

Summary

FeatureDjango
Admin panelAuto-generated from models
ORMPython queries → any SQL database
AuthUsers, groups, permissions built in
REST APIVia Django REST Framework
SecurityCSRF, XSS, SQL injection — default
ScaleInstagram (1B+ users) proves it

Django’s biggest win is speed of development — the Admin panel alone eliminates weeks of backoffice UI work. Use it when you need a complete web application, not just an API.

Related posts:


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. Build full-stack web applications with Django. Covers project setup, Models/ORM, Views, URL routing, Admin panel, Django…

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers Django, Python, Backend, MTV, ORM, REST API, Full Stack.