728x90
1. 환경 구축하기
- 가상환경 설정
python -m venv myshop
cd myshop
source ./bin/activate
# Windows의 경우 .\Scripts\activate
|
- 필수 라이브러리 설치
pip install -r requirements.txt
django, Pillow 두개만 import 해도 가능(후반부에는 다른 라이브러리도 필요) |
2. 온라인 상점 기반 구축
- 주요 기능
- 제품 카탈로그 만들기 → shop
- 광고 세션을 사용한 쇼핑 카트 구축 → cart
- 고객 주문관리 → order
2.1 제품 카탈로그 만들기
- 온라인 상점(쇼핑몰)은 실제 상품이 진열되는 것이 아니라 제품 카탈로그를 기반으로 구성됨
- 즉 제품 카탈로그를 만드는 작업이 온라인 상점의 기본 틀을 만드는 작업과 동일하다고 할 수 있음
2.1.1 기초 작업
- 프로젝트 생성
django-admin startproject myshop .
|
- 앱 생성
django-admin startapp shop
|
- 앱 등록(config/settings.py)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'shop.apps.ShopConfig',
]
|
2.1.2 제품 카탈로그 모델 생성
- 다양한 카테고리의 제품으로 구성됨
- 각 제품에는 이름, 설명(선택사항), 이미지(선택사항), 가격, 사용 가능성 등이 포함됨
- shop/models.py
from django.db import models
from django.urls import reverse
class Category(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
class Meta:
ordering = ['name']
indexes = [
models.Index(fields=['name']),
]
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_list_by_category', args=[self.slug])
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
name = models.CharField(max_length=200)
slug = models.SlugField(max_length=200)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['name']
indexes = [
models.Index(fields=['id', 'slug']),
models.Index(fields=['name']),
models.Index(fields=['-created']),
]
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_detail', args=[self.id, self.slug])
|
- Terminal
python manage.py makemigrations
python manage.py migrate
|
2.1.3 관리사이트(Admin)에 카탈로그 모델 등록하기
from django.contrib import admin
from .models import Category, Product
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'slug']
prepopulated_fields = {'slug': ('name',)}
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ['name', 'slug', 'price', 'available', 'created', 'updated']
list_filter = ['available', 'created', 'updated']
list_editable = ['price', 'available']
prepopulated_fields = {'slug': ('name',)}
|
- Terminal
python manage.py createsuperuser
python manage.py runserver
|
2.1.4 카탈로그 뷰 만들기
- shop/views.py
from django.shortcuts import render, get_object_or_404
from .models import Category, Product
def product_list(request, category_slug=None):
category = None
categories = Category.objects.all()
products = Product.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
products = products.filter(category=category)
return render(request, 'shop/product/list.html',
{'category': category, 'categories': categories, 'products': products})
def product_detail(request, id, slug):
product = get_object_or_404(Product, id=id, slug=slug, available=True)
return render(request, 'shop/product/detail.html',
{'product': product})
|
- shop/urls.py
from django.urls import path
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<slug:category_slug>/', views.product_list, name='product_list_by_category'),
path('<int:id>/<slug:slug>/', views.product_detail, name='product_detail'),
]
|
- myshop/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('shop.urls', namespace='shop')),
]
|
2.1.5 카탈로그 템플릿 생성하기
- shop/templates/shop/base.html
- 제품 목록 및 상세 페이지용 베이스 템플릿
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>{% block title %}My shop{% endblock %}</title>
<link href="{% static "css/base.css" %}" rel="stylesheet">
</head>
<body>
<div id="header">
<a href="/" class="logo">My shop</a>
</div>
<div id="subheader">
<div class="cart">
{% with total_items=cart|length %}
{% if total_items > 0 %}
Your cart:
<a href="{% url "cart:cart_detail" %}">
{{ total_items }} item{{ total_items|pluralize }},
${{ cart.get_total_price }}
</a>
{% elif not order %}
Your cart is empty.
{% endif %}
{% endwith %}
</div>
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
|
- shop/templates/product/list.html
- 제품 목록 템플릿
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{% if category %}{{ category.name }}{% else %}Products{% endif %}
{% endblock %}
{% block content %}
<div id="sidebar">
<h3>Categories</h3>
<ul>
<li {% if not category %}class="selected"{% endif %}>
<a href="{% url "shop:product_list" %}">All</a>
</li>
{% for c in categories %}
<li {% if category.slug == c.slug %}class="selected"{% endif %}>
<a href="{{ c.get_absolute_url }}">{{ c.name }}</a>
</li>
{% endfor %}
</ul>
</div>
<div id="main" class="product-list">
<h1>{% if category %}{{ category.name }}{% else %}Products{% endif %}</h1>
{% for product in products %}
<div class="item">
<a href="{{ product.get_absolute_url }}">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
</a>
<a href="{{ product.get_absolute_url }}">{{ product.name }}</a>
<br>
${{ product.price }}
</div>
{% endfor %}
</div>
{% endblock %}
|
- myshop/settings.py
MEDIA_URL = 'media/'
MEDIA_ROOT = BASE_DIR / 'media'
|
- myshop/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('shop.urls', namespace='shop')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
- shop/product/detail.html
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{{ product.name }}
{% endblock %}
{% block content %}
<div class="product-detail">
<img src="{% if product.image %}{{ product.image.url }}{% else %}
{% static "img/no_image.png" %}{% endif %}">
<h1>{{ product.name }}</h1>
<h2>
<a href="{{ product.category.get_absolute_url }}">
{{ product.category }}
</a>
</h2>
<p class="price">${{ product.price }}</p>
{{ product.description|linebreaks }}
</div>
{% endblock %}
|
728x90
'PYTHON-BACK' 카테고리의 다른 글
#파이썬 33일차_온라인 상점 구축 프로젝트3 (0) | 2024.08.27 |
---|---|
#파이썬 32일차_온라인 상점 구축 프로젝트2 (0) | 2024.08.26 |
#파이썬 34일차_이커머스 클론코딩5_(2) (0) | 2024.08.22 |
#파이썬 34일차_이커머스 클론코딩5_(1) (0) | 2024.08.22 |
#파이썬 34일차_이커머스 클론코딩4_(2) (0) | 2024.08.21 |