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

    +
  • +
+ +
+

{{ product.price.price_with_tax }}€

+ + +
+
+
+
\ 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.price.price_with_tax }} € +

+ +
+
+ + + + + +
+

+ (5.0) +

+ + 345 Reviews + +
+
+ + + +
+ +

+ {{ 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 %} +