Фильтр товаров с использованием модели категорий в Django
Я создаю сайт электронной коммерции и хочу фильтровать продукты с помощью категорий, но не знаю, как отобразить продукты. И добавить категории в навигационную панель, откуда люди могут переходить к различным категориям.
Вот мой views.py файл:
from django.shortcuts import render
from django.views import View
from .models import Product, Category
class ProductView(View):
def get(self, request, *args, **kwargs):
products = Product.objects.filter(is_active = True)
context = {
'products': products,
}
return render(request, 'Product/products.html', context)
class ProductDetailView(View):
def get(self, request, slug):
product = Product.objects.get(slug = slug)
context = {
'product': product
}
return render(request, 'Product/productdetail.html', context)
class CategoryView(View):
def get(self, request):
category = Category.objects.all()
products = Product.objects.filter(category__slug = slug)
context = {
'category': category,
'products':products,
}
return render(request, 'Product/category.html', context)
А это мой models.py
from django.db import models
from Seller.models import Seller
class Category(models.Model):
category = models.CharField(max_length = 255)
slug = models.SlugField(max_length = 255)
def __str__(self):
return self.category
class Product(models.Model):
product = models.ForeignKey(Seller, on_delete = models.CASCADE)
title = models.CharField(max_length = 255)
image = models.ImageField(upload_to = 'images', null = True, blank = True)
file = models.FileField(upload_to = 'files', null = True, blank = True)
actual_price = models.PositiveIntegerField(default = '0')
selling_price = models.PositiveIntegerField(default = '0')
slug = models.SlugField(max_length = 255, unique = True)
category = models.ForeignKey(Category, on_delete = models.CASCADE)
description = models.TextField()
is_active = models.BooleanField(default = True)
def __str__(self):
return self.title
Я также не знаю, как отобразить его в html.
Для рендеринга вам нужно будет использовать шаблоны Django. Их не очень сложно реализовать.
Шаблон может начинаться примерно так:
<html>
<body>
{% for product in products %}
<a href="products/{{ product.id }}">
<div>
<img src="{{ product.image.url }}">
<div>
<h3> {{ product.title }}</h3>
<p> {{ product.description|linebreaks }}</p>
</div>
</div>
</a>
{% endfor%}
</body>
</html>
Фильтрация товаров на основе категории проста:
products = Product.objects.filter(category__category='burger_buns')
Если вам нужно несколько категорий:
category_names = 'burger_buns sausages hammers'.split()
products = Product.objects.filter(category__category__in=category_names)
Или вы можете использовать обратный аксессор (подробнее здесь):
category = Category.objects.get(id=1)
products = category.product_set.all()
Я настоятельно рекомендую прочитать документацию по этому вопросу.
Когда вы определили отношение ForeignKey для Category
из Product
, также будет существовать обратное отношение. По умолчанию оно называется category.product_set
. Поэтому в вашем шаблоне, когда пользователь выбирает экземпляр категории, вы можете получить соответствующие ей товары с помощью category1.product_set
. Чтобы изменить это имя, определите related_name
для отношения ForeignKey.
category = models.ForeignKey(Category, related_name="products", on_delete = models.CASCADE)
Теперь, чтобы получить доступ к соответствующим товарам категории, просто сделайте что-то вроде category1.products
.
сначала нужно перейти в urls.py и сделать
urls.py в качестве примера
from .view import CategoryView
url_patterns =[
path("products/category/<slug:slug>/,CategoryView.as_view(),name="product-category")
]
в поле зрения
class CategoryView(View):
def get(self, request, slug):
category = Category.objects.all()
products = Product.objects.filter(category__slug = slug)
context = {
'category': category,
'products':products,
}
return render(request, 'Product/category.html', context)
Ваш вопрос составлен, тогда я отвечу на вопрос о категориях (Как показывать категории в навигационной панели и переходить по ним).
views.py
from django.views.generic.list import ListView
from .models import Category, Product
class CategoryListView(ListView):
model = Category
# Override the context_object_name, default is 'object_list'
context_object_name = 'categories'
# Assume that category_list.html is in app/templates/ folder
template_name = 'category_list.html'
class CategoryDetailView(DetailView):
model = Category
context_object_name = 'category' # Default is 'object'
# Assume that category_detail.html is in app/templates/ folder
template_name = 'category_detail.html'
# Add the product of this category to the context
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# This line retrieve all the products of this category
context['products'] = self.product_set.all()
return context
urls.py
from django.urls import path
from .views import CategoryListView, CategoryDetailView
urlpatterns = [
path('category/', CategoryListView.as_view(), name='category-list'),
path('category/<slug:slug>/', CategoryDetailView.as_view(), name='category-detail'),
]
category_list.html
<h1 class="head">Products Categories</h1>
{% for cat in categories %}
<div>
<a href="{% url 'category-detail' cat.slug %}">
<h3>{{ cat.category }}</h3>
</a>
</div>
{% endfor %}
</div>
category_detail.html
<h1 class="head">{{ category.category }}</h1>
<h3>Products for this category</h3>
<div>
{% for product in products %}
<div>
<h5>{{ product.title }}<h5/>
<div>{{ product.description }}</div>
<img src="{{ product.image.url }}"/>
</div>
{% endfor %}
</div>