μΌνλͺ° κΈ°λ³Έ νμ΄μ§
μΌνλͺ° κΈ°λ³Έ νμ΄μ§λ₯Ό λ§λ€μ΄λ΄
λλ€.
1.
λ©μΈ νλ©΄
2.
μν λͺ©λ‘
3.
μν μμΈ
νλ‘μ νΈ κ΅¬μ‘°
Django νλ‘μ νΈμ κΈ°λ³Έ λλ ν 리 ꡬ쑰λ λ€μκ³Ό κ°μ΅λλ€:
μ΄ κ΅¬μ‘°λ Djangoμ νμ€ νλ‘μ νΈ λ μ΄μμμ λ°λ₯΄λ©°, μ μ νμΌ, λ―Έλμ΄ νμΌ, ν
νλ¦Ώ λ±μ΄ 체κ³μ μΌλ‘ ꡬμ±λμ΄ μμ΅λλ€.
graph TD; A["λ©μΈ νμ΄μ§ (main.html)"] --> B["μν λͺ©λ‘ (product_list.html)"]; B --> C["μν μμΈ (product_detail.html)"]; D["Models"] --> E["Product"]; E --> F["name"]; E --> G["price"]; E --> H["description"]; E --> I["image"]; J["Views"] --> K["main()"]; J --> L["product_list()"]; J --> M["product_detail()"]; N["URLs"] --> O["/ (main)"]; N --> P["/products/ (list)"]; N --> Q["/products/<pk>/ (detail)"];
Mermaid
볡μ¬
μμ ꡬ쑰λλ Django νλ‘μ νΈμ κΈ°λ³Έ ꡬ쑰μ μ£Όμ μ»΄ν¬λνΈλ€ κ°μ κ΄κ³λ₯Ό 보μ¬μ€λλ€. λ©μΈ νμ΄μ§μμ μν λͺ©λ‘μΌλ‘, κ·Έλ¦¬κ³ μν μμΈ νμ΄μ§λ‘ μ΄μ΄μ§λ μ¬μ©μ νλ¦κ³Ό ν¨κ» λͺ¨λΈ, λ·°, URLμ ꡬμ±μ νννκ³ μμ΅λλ€.
κ°λ° νλ‘μΈμ€
1.
νλ‘μ νΈ νκ²½ μ€μ
β’
κ°μνκ²½ μμ± λ° νμ±ν
β’
Django λ° νμν ν¨ν€μ§ μ€μΉ
β’
νλ‘μ νΈ μμ±
2.
κΈ°λ³Έ ꡬ쑰 μ€μ
β’
μ± μμ±
β’
settings.py μ€μ
β’
URL λ§€ν
3.
νλ‘ νΈμλ ꡬμ±
β’
Bootstrap μ€μΉ
β’
κΈ°λ³Έ ν
νλ¦Ώ ꡬ쑰 μμ±
β’
static νμΌ μ€μ
4.
λ°±μλ κ°λ°
β’
λͺ¨λΈ μ€κ³ λ° κ΅¬ν
β’
λ·° λ‘μ§ μμ±
β’
νΌ μμ±
5.
ν
μ€νΈ λ° λ°°ν¬
β’
λ¨μ ν
μ€νΈ μμ±
β’
ν΅ν© ν
μ€νΈ
β’
λ°°ν¬ μ€λΉ
μ£Όμ λͺ λ Ήμ΄ λ° μ½λ
1. νλ‘μ νΈ νκ²½ μ€μ
κ°μνκ²½ μμ±
python -m venv venv
Python
볡μ¬
κ°μνκ²½ νμ±ν
venv\Scripts\activate
Python
볡μ¬
Django μ€μΉ
pip install django
Python
볡μ¬
νλ‘μ νΈ μμ±
django-admin startproject shop_project .
Python
볡μ¬
2. μ± μμ± λ° μ€μ
μ± μμ±
python manage.py startapp shop
Bash
볡μ¬
settings.pyμμ μ±κ³Ό ν
νλ¦Ώ μ€μ :
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'shop',
'bootstrap5', # Bootstrap 5 μ¬μ©
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Python
볡μ¬
3. URL λ§€ν
# shop_project/urls.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('shop.urls')),
]
# shop/urls.py
from django.urls import path
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.main, name='main'),
path('products/', views.product_list, name='product_list'),
path('products/<int:pk>/', views.product_detail, name='product_detail'),
]
Python
볡μ¬
κ° URL ν¨ν΄μ λν μ€λͺ
:
1. λ©μΈ νμ΄μ§ URL
path('', views.main, name='main')
Python
볡μ¬
β’
β’
views.main ν¨μλ₯Ό νΈμΆνμ¬ λ©μΈ νμ΄μ§λ₯Ό νμν©λλ€
β’
name='main'μ μ΄ URL ν¨ν΄μ μ΄λ¦μΌλ‘, ν
νλ¦Ώμμ {% url 'shop:main' %}κ³Ό κ°μ΄ μ°Έμ‘°ν μ μμ΅λλ€
2. μν λͺ©λ‘ URL
path('products/', views.product_list, name='product_list')
Python
볡μ¬
β’
β’
views.product_list ν¨μλ₯Ό νΈμΆνμ¬ μ 체 μν λͺ©λ‘μ νμν©λλ€
β’
name='product_list'λ‘ μ΄λ¦μ΄ μ§μ λμ΄ μμ΄ ν
νλ¦Ώμμ {% url 'shop:product_list' %}λ‘ μ°Έμ‘° κ°λ₯ν©λλ€
3. μν μμΈ URL
path('products/<int:pk>/', views.product_detail, name='product_detail')
Python
볡μ¬
β’
β’
<int:pk>λ URL ν¨ν΄μ λμ λΆλΆμΌλ‘, μ μν primary keyλ₯Ό μΊ‘μ²ν©λλ€
β’
views.product_detail ν¨μμ pk λ§€κ°λ³μλ‘ μ λ¬λμ΄ νΉμ μνμ μμΈ μ 보λ₯Ό νμν©λλ€
β’
4. κΈ°λ³Έ ν νλ¦Ώ ꡬ쑰
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}μΌνλͺ°{% endblock %}</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<!-- λ€λΉκ²μ΄μ
λ° λ΄μ© -->
</nav>
<div class="container mt-4">
{% block content %}
{% endblock %}
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
HTML
볡μ¬
6. ν νλ¦Ώ μμ±
β’
main.html
β’
product_list.html
β’
product_detail.html
main.html
<!-- templates/shop/main.html -->
{% extends 'base.html' %}
{% block title %}λ©μΈ νμ΄μ§{% endblock %}
{% block content %}
<div class="jumbotron">
<h1>Welcome to Our Shop</h1>
<p>μ΅κ³ μ μνμ μ΅μ κ°λ‘ λ§λ보μΈμ!</p>
<a href="{% url 'shop:product_list' %}" class="btn btn-primary">μν 보λ¬κ°κΈ°</a>
</div>
{% endblock %}
HTML
볡μ¬
product_list.html
<!-- templates/shop/product_list.html -->
{% extends 'base.html' %}
{% block title %}μν λͺ©λ‘{% endblock %}
{% block content %}
<h2>μν λͺ©λ‘</h2>
<div class="row">
{% for product in products %}
<div class="col-md-4 mb-4">
<div class="card">
{% if product.image %}
<img src="{{ product.image.url }}" class="card-img-top" alt="{{ product.name }}">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">{{ product.price }}μ</p>
<a href="{% url 'shop:product_detail' product.pk %}" class="btn btn-primary">μμΈλ³΄κΈ°</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
HTML
볡μ¬
product_detail.html
<!-- templates/shop/product_detail.html -->
{% extends 'base.html' %}
{% block title %}{{ product.name }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-6">
{% if product.image %}
<img src="{{ product.image.url }}" class="img-fluid" alt="{{ product.name }}">
{% endif %}
</div>
<div class="col-md-6">
<h2>{{ product.name }}</h2>
<p class="lead">κ°κ²©: {{ product.price }}μ</p>
<hr>
<p>{{ product.description }}</p>
<button class="btn btn-primary">μ₯λ°κ΅¬λμ λ΄κΈ°</button>
</div>
</div>
{% endblock %}
HTML
볡μ¬
5. λͺ¨λΈ μμ±
# shop/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField()
image = models.ImageField(upload_to='products/')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
Python
볡μ¬
κ° λͺ¨λΈ νλμ λν μ€λͺ
:
β’
name: μνλͺ
μ μ μ₯νλ CharField, μ΅λ 200μκΉμ§ μ
λ ₯ κ°λ₯
β’
price: κ°κ²©μ μ μ₯νλ DecimalField, μ΅λ 10μ리 μ«μμ μμμ 2μ리κΉμ§ μ§μ
β’
description: μν μ€λͺ
μ μ μ₯νλ TextField, κΈΈμ΄ μ ν μμ
β’
image: μν μ΄λ―Έμ§λ₯Ό μ μ₯νλ ImageField, 'products/' λλ ν 리μ μ
λ‘λλ¨
β’
created_at: μν μμ± μκ°μ μλμΌλ‘ μ μ₯νλ DateTimeField
β’
updated_at: μν μ 보 μμ μκ°μ μλμΌλ‘ μ
λ°μ΄νΈνλ DateTimeField
# settings.py
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'upload')
Python
볡μ¬
μ€μ λ‘ __file__μ νμ¬ νμΌ(settings.py)μ κ²½λ‘λ§μ κ°λ¦¬ν΅λλ€. os.path.dirnameμ λ λ² μ¬μ©νμ¬:
β’
첫 λ²μ§Έ dirname: settings.pyκ° μλ λλ ν 리(shop_project)μ κ²½λ‘λ₯Ό μ»μ
β’
λ λ²μ§Έ dirname: νλ‘μ νΈ λ£¨νΈ λλ ν 리μ κ²½λ‘λ₯Ό μ»μ
λ°λΌμ BASE_DIR = os.path.dirname(os.path.dirname(file))μ κ°μ΄ μ€μ νλ©΄ λ λͺ
νν κ² κ°μ΅λλ€:
μ΄λ κ² νλ©΄ νλ‘μ νΈ λ£¨νΈ λλ ν 리μ 'upload' ν΄λκ° μμ±λ©λλ€. μ€μ κ²½λ‘λ νλ‘μ νΈκ° μλ μμΉμ λ°λΌ λ¬λΌμ§ μ μμ΅λλ€.
μ₯κ³ νλ‘μ νΈμ URLsμμ λ―Έλμ΄ νμΌμ μλΉνκΈ° μν μ€μ :
# urls.py (νλ‘μ νΈ λ©μΈ)
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Python
볡μ¬
μ λ‘λ ν΄λ μμ±
C:\
βββ ~
βββ shop_project\
βββ manage.py
βββ shop_app\
βββ shop_project\
βββ π¦ upload\ β μ¬κΈ°μ μμ± (μλ)
Python
볡μ¬
λͺ¨λΈ μμ± ν λ§μ΄κ·Έλ μ΄μ :
λ§μ΄κ·Έλ μ΄μ μ΄λ (Migration)?
λ§μ΄κ·Έλ μ΄μ
μ λ°μ΄ν°λ² μ΄μ€μ ꡬ쑰λ₯Ό λ³κ²½νλ μμ
μ 체κ³μ μΌλ‘ κ΄λ¦¬νλ Djangoμ κΈ°λ₯μ
λλ€. μ£Όμ νΉμ§μ λ€μκ³Ό κ°μ΅λλ€:
β’
λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§ λ²μ κ΄λ¦¬: λͺ¨λΈ λ³κ²½μ¬νμ μΆμ νκ³ λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§λ₯Ό μμ νκ² μ
λ°μ΄νΈ
β’
νμ
μ§μ: μ¬λ¬ κ°λ°μκ° λμμ μμ
ν λ λ°μ΄ν°λ² μ΄μ€ λ³κ²½μ¬νμ μΌκ΄λκ² κ΄λ¦¬
β’
λ‘€λ°± κ°λ₯: λ¬Έμ λ°μ μ μ΄μ μνλ‘ λλ릴 μ μλ κΈ°λ₯ μ 곡
β’
μλ SQL μμ±: κ°λ°μκ° μ§μ SQLμ μμ±νμ§ μμλ Djangoκ° μ μ ν SQL λͺ
λ Ήμ΄λ₯Ό μμ±
λ§μ΄κ·Έλ μ΄μ
μ λ λ¨κ³λ‘ μ΄λ£¨μ΄μ§λλ€:
1.
makemigrations: λͺ¨λΈμ λ³κ²½μ¬νμ κ°μ§νμ¬ λ§μ΄κ·Έλ μ΄μ
νμΌμ μμ±
2.
migrate: μμ±λ λ§μ΄κ·Έλ μ΄μ
νμΌμ μ€μ λ°μ΄ν°λ² μ΄μ€μ μ μ©
β’
λ§μ΄κ·Έλ μ΄μ
νμΌ μμ±
python manage.py makemigrations
Bash
볡μ¬
μ΄ λͺ
λ Ήμ΄λ λͺ¨λΈμ λ³κ²½μ¬νμ κ°μ§νκ³ μλ‘μ΄ λ§μ΄κ·Έλ μ΄μ
νμΌμ μμ±ν©λλ€. λ§μ΄κ·Έλ μ΄μ
νμΌμ λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§λ₯Ό λ³κ²½νκΈ° μν Python μ½λμ
λλ€.
β’
λ§μ΄κ·Έλ μ΄μ
python manage.py migrate
Bash
볡μ¬
μ΄ λͺ
λ Ήμ΄λ μμ±λ λ§μ΄κ·Έλ μ΄μ
νμΌμ μ€μ λ°μ΄ν°λ² μ΄μ€μ μ μ©ν©λλ€. μ΄λ₯Ό ν΅ν΄ λͺ¨λΈμμ μ μν ν
μ΄λΈμ΄ λ°μ΄ν°λ² μ΄μ€μ μμ±λ©λλ€.
λ§μ΄κ·Έλ μ΄μ
μ λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§ λ³κ²½μ μΆμ νκ³ κ΄λ¦¬νλ Djangoμ λ°©λ²μ
λλ€. μ΄λ₯Ό ν΅ν΄ μ¬λ¬ κ°λ°μκ° νμ
νκ±°λ λ°μ΄ν°λ² μ΄μ€ λ³κ²½ μ΄λ ₯μ κ΄λ¦¬ν μ μμ΅λλ€.