Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

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を追加する。