diff --git a/config/settings/base.py b/config/settings/base.py
index 8381d27..1802d1b 100644
--- a/config/settings/base.py
+++ b/config/settings/base.py
@@ -218,3 +218,5 @@ SIMPLE_JWT = {
}
TAILWIND_APP_NAME = "theme"
+
+ITEMS_PER_PAGE = 10
diff --git a/shop/api/v1/viewsets.py b/shop/api/v1/viewsets.py
index ec33996..dca6f28 100644
--- a/shop/api/v1/viewsets.py
+++ b/shop/api/v1/viewsets.py
@@ -9,7 +9,7 @@ from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAdminUser
-from shop.api.v1.filters import ProductFilter
+from shop.filters import ProductFilter
from shop.api.v1.serializers import (
ProductSerializer,
ProductPriceSerializer,
diff --git a/shop/api/v1/filters.py b/shop/filters.py
similarity index 100%
rename from shop/api/v1/filters.py
rename to shop/filters.py
diff --git a/shop/management/__init__.py b/shop/management/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/shop/management/commands/__init__.py b/shop/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/shop/mixins.py b/shop/mixins.py
new file mode 100644
index 0000000..f0b87a4
--- /dev/null
+++ b/shop/mixins.py
@@ -0,0 +1,27 @@
+from django.conf import settings
+from django.core.paginator import Paginator
+
+
+class FilteredQuerysetMixin:
+ queryset = None
+ filter_class = None
+
+ def get_filter_class(self):
+ return self.filter_class
+
+ def get_queryset(self):
+ filter_cls = self.get_filter_class()
+ filter_obj = filter_cls(self.request.GET)
+ filter_obj.is_valid()
+ qs = filter_obj.filter_queryset(self.queryset)
+ return qs
+
+
+class PaginatedQuerysetMixin:
+ objects_per_page = settings.ITEMS_PER_PAGE or 20
+
+ def get_paginated_queryset(self, qs):
+ paginator = Paginator(qs, self.objects_per_page)
+ page = self.request.GET.get("page", 1)
+ qs = paginator.get_page(page)
+ return qs
diff --git a/shop/templates/components/product_card.html b/shop/templates/components/product_card.html
new file mode 100644
index 0000000..2b54360
--- /dev/null
+++ b/shop/templates/components/product_card.html
@@ -0,0 +1,90 @@
+
+
+
+
+
+
{{ product.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
5.0
+
(455)
+
+
+
+ -
+
+
Fast Delivery
+
+
+ -
+
+
Best Price
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/shop/templates/shop/index.html b/shop/templates/shop/index.html
new file mode 100644
index 0000000..ef36639
--- /dev/null
+++ b/shop/templates/shop/index.html
@@ -0,0 +1,9 @@
+{% extends 'theme/base.html' %}
+
+{% load static %}
+
+{% block main %}
+
+
+
+{% endblock %}
diff --git a/shop/templates/shop/list_products.html b/shop/templates/shop/list_products.html
new file mode 100644
index 0000000..de9b3ad
--- /dev/null
+++ b/shop/templates/shop/list_products.html
@@ -0,0 +1,21 @@
+{% extends 'theme/base.html' %}
+
+{% load static %}
+
+{% block main %}
+
+
+
+ {% for product in products %}
+ {% include 'components/product_card.html' %}
+ {% endfor %}
+
+
+
+
+
+
+{% endblock %}
diff --git a/shop/templates/shop/product_detail.html b/shop/templates/shop/product_detail.html
new file mode 100644
index 0000000..28acae5
--- /dev/null
+++ b/shop/templates/shop/product_detail.html
@@ -0,0 +1,174 @@
+{% extends 'theme/base.html' %}
+
+{% load static %}
+
+{% block main %}
+
+
+
+
+
+

+

+
+
+
+
+ {{ product.name }}
+
+
+
+
+
+
+
+
+ {{ product.description }}
+
+
+
+
+
+{% endblock %}
diff --git a/shop/urls.py b/shop/urls.py
index 3b2da6c..f971ec0 100644
--- a/shop/urls.py
+++ b/shop/urls.py
@@ -1,9 +1,11 @@
from django.urls import path
-from shop.views import index
+from shop.views import index, list_products, product_detail
app_name = "shop"
urlpatterns = [
path("", index, name="index"),
+ path("products//", product_detail, name="product_detail"),
+ path("shop/components/products/", list_products, name="list_products"),
]
diff --git a/shop/views.py b/shop/views.py
index ac0316b..da0bae6 100644
--- a/shop/views.py
+++ b/shop/views.py
@@ -1,7 +1,42 @@
-from django.http.response import HttpResponse
-from django.shortcuts import render
+from django.views.generic import TemplateView
+from django.shortcuts import get_object_or_404
+from django.core.paginator import Paginator
+
+from shop.filters import ProductFilter
+from shop.models import Product
+
+from shop.mixins import FilteredQuerysetMixin, PaginatedQuerysetMixin
-# Create your views here.
-def index(request, *args, **kwargs):
- return HttpResponse("Hello there")
+class IndexView(TemplateView):
+ template_name = "shop/index.html"
+
+
+class ListProducts(TemplateView, FilteredQuerysetMixin, PaginatedQuerysetMixin):
+ template_name = "shop/list_products.html"
+ queryset = Product.objects.all()
+ filter_class = ProductFilter
+
+ def get_context_data(self, **kwargs):
+ qs = self.get_queryset()
+ products = self.get_paginated_queryset(qs)
+
+ return {
+ "products": products,
+ }
+
+
+class ProductDetail(TemplateView):
+ template_name = "shop/product_detail.html"
+
+ def get_context_data(self, pk, **kwargs):
+ product = get_object_or_404(Product, pk=pk)
+
+ return {
+ "product": product,
+ }
+
+
+index = IndexView.as_view()
+list_products = ListProducts.as_view()
+product_detail = ProductDetail.as_view()
diff --git a/theme/templates/theme/base.html b/theme/templates/theme/base.html
index 700bc3e..26831d2 100644
--- a/theme/templates/theme/base.html
+++ b/theme/templates/theme/base.html
@@ -13,8 +13,10 @@
{% endblock %}
+
{% block main %}
{% endblock %}
+