Djangoでショッピングカートを作りたい3

一覧から画像をクリックすると遷移する商品詳細ページを作成します。

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>

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