一覧から画像をクリックすると遷移する商品詳細ページを作成します。
shop/models.py
L reverseとは、Djangoのurlsに設定された名前をパラメータとして渡すとURLを返す。
from django.urls import reverse class Product(models.Model): // 省略 def get_url(self): return reverse('shop:product_detail', args=[self.slug])
shop/urls.py
app_name = 'shop' urlpatterns = [ // 省略 path('<slug:product_slug/>', views.product_detail, name='product_detail'), ]
shop/views.py
def product_detail(request, product_slug): try: product = Product.objects.get(slug=product_slug) except Exception as e: raise e return render(request, 'shop/product_detail.html', {'product': product})
shop/templates/shop/product_detail.html
{% extends "base.html" %} {% load static %} {% block metadescription %} {{ product.description|truncatewords:155}} {% endblock %} {% block title %} {{ product.name }} - Perfect Cushion Store {% endblock %} {% block content %} <div> <div> <p><a href="{% url 'shop:all_product' %}">Home</a>|<a href="{{product.get_url}}">{{product.category}}</a></p> </div> <div> <br> <div> <div> <div> <img src="{{product.image.url}}" alt="{{product.name}}"> </div> </div> <div> <div> <h1>{{product.name}}</h1> <p>${{product.price}}</p> <p>Product Description</p> <p>{{product.description}}</p> {% if product.stock <= 0 %} <p><b>Out of Stock</b></p> {% else %} <a href="">Add to Cart</a> {% endif %} </div> </div> </div> </div> </div> {% endblock %}
shop/templates/shop/product_list.html
<div> <a href="{{product.get_url}}"><img src="{{ product.image.url }}" alt="{{product.name}}"></a> <div> <h4>{{product.name}}</h4> <p>${{product.price}}</p> </div> </div>
static/css/custom.css
.nav-item { letter-spacing: .2em; font-size: 14px; text-transform: uppercase; } .dropdown-item { font-size: 14px; letter-spacing: .2em; text-transform: uppercase; } /* google font */ body { font-family: 'Roboto', sans-serif; } .my_footer { background-color: #f8f9fa; height: 60px; } .my_footer p { padding-top: 20px; font-size: 14px; }
base.html
<link rel="stylesheet" href="{% static 'css/custom.css' %}"> <link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
スタイリングをしていきます。
orange, bananaを追加します。
### ページネーション
views.py
from django.core.paginator import Paginator, EmptyPage, InvalidPage def all_products(request): products = Product.valid_objects.all() paginator = Paginator(products_list, 3) try: page = int(request.GET.get('page','1')) except: page = 1 try: products = paginator.page(page) except (EmptyPage, InvalidPage): products = paginator.page(paginator.num_pages) return render(request, 'shop/product_list.html',{'products':products})
product_list.html
<div class="row"> <div class="mx-auto"> {% if products.paginator.num_pages > 1%} <hr> <div class="text-center"> {% for pg in products.paginator.page_range %} <a href="?page={{pg}}" class="btn btn-light btn-sm {% if products.number == pg %}active{% endif %}">{{pg}}</a> {% endfor %} </div> {% endif %} </div> </div>
商品数が多い場合は使えないけど、こういう書き方があるんやな