Django e-commerce part26 Category Detail View
Categoryのdetailviewを作成する
products/urls_categories.py を作成する
products/urls_categories.py 新規ファイルを作成する。 products/ulrs.pyをコピペする。
products/views.py にcategory viewを追記していく
from .models import Product, Variation, Category ... class CategoryListView(ListView): model = Category queryset = Category.objects.all() ...
urls_categories.py にcategorylistviewを追記する
urlpatterns = [ url(r'^$', CategoryListView.as_view(), name='categories'), ]
ecommerce2/urls.py にurls_categoriesを紐付ける。
urlpatterns = [ ... url(r'^categories/', include('products.urls_categories')), ... ]
products/category_list.html templateview を作成する。
category_list.html を作成する前に、CategoryListViewに、products/product_list.html
を指定してテストしてみる。指定する場合は、template_name = "文字列" になるので注意。
... template_name = "products/product_list.html" ...
products/views.py に、CategoryDetailView を作成する
class CategoryDetailView(DetailView): model = Category
urls_categories.py に、CategoryDetailView を追記する
ここではslugを使って設定してみる。
url(r'^(?P<slug>[\w-]+)/$', CategoryDetailView.as_view(), name='category_detail'),
models.py のCategory にget_absolute_urlを追記する
class Category(models.Model): ... def get_absolute_url(self): return reverse("category_detail", kwargs={"slug": self.slug}) ...
reverse("urlsで設定したurlpatternの名前", kwargs=で渡したいフィールドとかの名前)
products/category_detail.html を作成する
{% extends "base.html" %} {% block content %} <h3>{{ object }}</h3> <table class='table'> {% for product in object.product_set.all %} <tr> <td><a href='{{ product.get_absolute_url }}'>{{ product.title }}</td> </tr> {% endfor %} </table> {% endblock %}
views.py CategoryDetailView にproductsのcontextを追記する。
class CategoryDetailView(DetailView): model = Category def get_context_data(self, *args, **kwargs): context = super(CategoryDetailView, self).get_context_data(*args, **kwargs) obj = self.get_object() product_set = obj.product_set.all() default_products = obj.default_category.all() products = ( product_set | default_products ).distinct() context["products"] = products return context
これは何をしたいかというと、Product Modelには、categories と default という異なるカテゴリーがあると思うが、category detail viewには、defaultとcategoriesそれぞれにどちらに登録されていても、同じcategoryとして、表示されるように、まとめてリスト化したいということだと思う。
obj = self.get_object()
で、categoryのオブジェクトをゲットproduct_set = obj.product_set.all()
で、categoriesに登録されているproduct_setをゲットdefault_products = obj.default_category.all()
で、defaultに登録されているproductをゲットする。default_categoryは、models.pyで設定したrelated_nameを使う。products = ( product_set | default_products ).distinct()
は、product_set, default_products を合体して、distinct()で重複を排除したオブジェクトリスト.context["products"] = products
で、contextを追加する。