Создание представления каталога

Чтобы отобразить каталог продуктов, необходимо создать представление для списка всех продуктов или фильтрации продуктов по данной категории. Измените файл views.py приложения shop и добавьте в него следующий код:

from django.shortcuts import render, get_object_or_404
from .models import Category, Product


def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)
    return render(request,
                  'shop/product/list.html',
                  {'category': category,
                   'categories': categories,
                   'products': products})

Мы отфильтруем запрос с available=True, чтобы получить только доступные продукты. Мы будем использовать необязательный параметр category_slug, чтобы дополнительно фильтровать продукты по данной категории.

Также требуется представление для извлечения и отображения одного продукта. Добавьте следующий view в файл views.py:

from django.shortcuts import render, get_object_or_404
from .models import Category, Product


def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)
    return render(request,
                  'shop/product/list.html',
                  {'category': category,
                   'categories': categories,
                   'products': products})


def product_detail(request, id, slug):
    product = get_object_or_404(Product,
                                id=id,
                                slug=slug,
                                available=True)
    return render(request,
                  'shop/product/detail.html',
                  {'product': product})

Для получения экземпляра Product в product_detail view рассчитываются параметры id и slug. Этот экземпляр можно получить только с помощью id, поскольку он является уникальным атрибутом. Тем не менее, в URL-адрес можно добавить slug для создания удобных URL-адресов для продуктов.

После построения product list и detail views необходимо определить шаблоны URL-адресов. Создайте новый файл в каталоге приложения shop и назовите его urls.py Добавьте в него следующий код:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.product_list, name='product_list'),
    url(r'^(?P<category_slug>[-\w]+)/$',
        views.product_list,
        name='product_list_by_category'),
    url(r'^(?P<id>\d+)/(?P<slug>[-\w]+)/$',
        views.product_detail,
        name='product_detail'),
]

Это шаблоны URL-адресов для каталога продуктов. Мы определили два различных шаблона URL-адреса для представления product_list: шаблон с именем product_list, который вызывает product_list view без каких-либо параметров; и шаблон с именем product_list_by_category, который предоставляет параметр category_slug в представлении для фильтрации продуктов по данной категории. Мы добавили шаблон для выносного элемента product_detail, который передает в представление параметры id и slug для извлечения конкретного продукта.

Измените файл urls.py проекта myshop:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^', include('shop.urls', namespace='shop')),
]

В основных URL-шаблонах проекта будут включены URL-адреса для приложения shop в пользовательском пространстве имен с именем 'shop'.

Теперь отредактируйте файл models.py приложения shop, импортируйте функцию reverse() и добавьте метод get_absolute_url() в модели Category и Product:

from django.core.urlresolvers import reverse
# ...
class Category(models.Model):
    # ...
    def get_absolute_url(self):
        return reverse('shop:product_list_by_category',
                        args=[self.slug])

class Product(models.Model):
    # ...
    def get_absolute_url(self):
        return reverse('shop:product_detail',
                        args=[self.id, self.slug])

Как вы уже знаете, get_absolute_url() — это Конвенция для получения URL-адреса данного объекта. Здесь мы будем использовать шаблоны URL-адресов, которые мы только что определили в файле urls.py.

results matching ""

    No results matching ""