一覧から画像をクリックすると遷移する商品詳細ページを作成します。
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>

商品数が多い場合は使えないけど、こういう書き方があるんやな












