diff --git a/apps/product/models.py b/apps/product/models.py index 2f964627..fe169903 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -111,6 +111,14 @@ class ProductQuerySet(models.QuerySet): """Filter by subtype.""" return self.filter(subtypes__index_name=product_subtype) + def by_country_code(self, country_code): + """Filter by country of produce.""" + return self.filter(establishment__address__city__country__code=country_code) + + def published(self): + """Filter products by published state.""" + return self.filter(state=self.model.PUBLISHED) + class Product(TranslatedFieldsMixin, BaseAttributes): """Product models.""" @@ -258,7 +266,8 @@ class Product(TranslatedFieldsMixin, BaseAttributes): @property def related_tags(self): return self.tags.exclude( - category__index_name__in=['sugar-content', 'wine-color', 'bottles-produced']) + category__index_name__in=['sugar-content', 'wine-color', 'bottles-produced', + 'serial-number']) class OnlineProductManager(ProductManager): diff --git a/apps/product/serializers/back.py b/apps/product/serializers/back.py index 9c98dff1..630a815a 100644 --- a/apps/product/serializers/back.py +++ b/apps/product/serializers/back.py @@ -4,7 +4,8 @@ from rest_framework import serializers from gallery.models import Image from product import models -from product.serializers import ProductDetailSerializer, ProductTypeBaseSerializer +from product.serializers import ProductDetailSerializer, ProductTypeBaseSerializer, \ + ProductSubTypeBaseSerializer from tag.models import TagCategory @@ -65,16 +66,6 @@ class ProductBackOfficeDetailSerializer(ProductDetailSerializer): 'wine_village', 'state', ] - extra_kwargs = { - 'description': {'write_only': True}, - 'available': {'write_only': True}, - 'product_type': {'write_only': True}, - 'establishment': {'write_only': True}, - 'wine_region': {'write_only': True}, - 'wine_sub_region': {'write_only': True}, - 'wine_village': {'write_only': True}, - 'state': {'write_only': True}, - } class ProductTypeBackOfficeDetailSerializer(ProductTypeBaseSerializer): @@ -84,14 +75,8 @@ class ProductTypeBackOfficeDetailSerializer(ProductTypeBaseSerializer): """Meta class.""" fields = ProductTypeBaseSerializer.Meta.fields + [ 'name', - 'index_name', 'use_subtypes', ] - extra_kwargs = { - 'name': {'write_only': True}, - 'index_name': {'write_only': True}, - 'use_subtypes': {'write_only': True}, - } class ProductTypeTagCategorySerializer(serializers.ModelSerializer): @@ -105,7 +90,7 @@ class ProductTypeTagCategorySerializer(serializers.ModelSerializer): class Meta(ProductTypeBaseSerializer.Meta): """Meta class.""" - fields = ProductTypeBaseSerializer.Meta.fields + [ + fields = [ 'product_type_id', 'tag_category_id', ] @@ -130,3 +115,15 @@ class ProductTypeTagCategorySerializer(serializers.ModelSerializer): product_type.tag_categories.add(tag_category) return product_type + + +class ProductSubTypeBackOfficeDetailSerializer(ProductSubTypeBaseSerializer): + """Product sub type back-office detail serializer.""" + + class Meta(ProductSubTypeBaseSerializer.Meta): + """Meta class.""" + fields = ProductSubTypeBaseSerializer.Meta.fields + [ + 'product_type', + 'name', + 'index_name', + ] diff --git a/apps/product/serializers/common.py b/apps/product/serializers/common.py index 1562016f..930221c3 100644 --- a/apps/product/serializers/common.py +++ b/apps/product/serializers/common.py @@ -12,13 +12,27 @@ from utils import exceptions as utils_exceptions from utils.serializers import TranslatedField, FavoritesCreateSerializer from main.serializers import AwardSerializer from location.serializers import WineRegionBaseSerializer, WineSubRegionBaseSerializer -from tag.serializers import TagBaseSerializer +from tag.serializers import TagBaseSerializer, TagCategoryShortSerializer + + +class ProductTagSerializer(TagBaseSerializer): + """Serializer for model Tag.""" + + category = TagCategoryShortSerializer(read_only=True) + + class Meta(TagBaseSerializer.Meta): + """Meta class.""" + + fields = TagBaseSerializer.Meta.fields + ( + 'category', + ) class ProductSubTypeBaseSerializer(serializers.ModelSerializer): """ProductSubType base serializer""" name_translated = TranslatedField() - index_name_display = serializers.CharField(source='get_index_name_display') + index_name_display = serializers.CharField(source='get_index_name_display', + read_only=True) class Meta: model = models.ProductSubType @@ -32,15 +46,13 @@ class ProductSubTypeBaseSerializer(serializers.ModelSerializer): class ProductTypeBaseSerializer(serializers.ModelSerializer): """ProductType base serializer""" name_translated = TranslatedField() - index_name_display = serializers.CharField(source='get_index_name_display', - read_only=True) class Meta: model = models.ProductType fields = [ 'id', 'name_translated', - 'index_name_display', + 'index_name', ] @@ -76,7 +88,7 @@ class ProductBaseSerializer(serializers.ModelSerializer): product_type = serializers.CharField(source='product_type_translated_name', read_only=True) subtypes = ProductSubTypeBaseSerializer(many=True, read_only=True) establishment_detail = EstablishmentShortSerializer(source='establishment', read_only=True) - tags = TagBaseSerializer(source='related_tags', many=True, read_only=True) + tags = ProductTagSerializer(source='related_tags', many=True, read_only=True) preview_image_url = serializers.URLField(source='preview_main_image_url', allow_null=True, read_only=True) diff --git a/apps/product/urls/back.py b/apps/product/urls/back.py index 41ed3766..7d3b1611 100644 --- a/apps/product/urls/back.py +++ b/apps/product/urls/back.py @@ -17,11 +17,8 @@ urlpatterns = [ path('types/attach-tag-category/', views.ProductTypeTagCategoryCreateBackOfficeView.as_view(), name='type-tag-category-create'), # product sub types - # path('subtypes/', views.ProductSubTypeListCreateBackOfficeView.as_view(), - # name='subtype-list-create'), - # path('subtypes//', views.ProductSubTypeRUDBackOfficeView.as_view(), - # name='subtype-retrieve-update-destroy'), - # path('subtypes/attach-tag-category/', views.ProductSubTypeTagCategoryCreateBackOfficeView.as_view(), - # name='subtype-tag-category-create'), - + path('subtypes/', views.ProductSubTypeListCreateBackOfficeView.as_view(), + name='subtype-list-create'), + path('subtypes//', views.ProductSubTypeRUDBackOfficeView.as_view(), + name='subtype-retrieve-update-destroy'), ] diff --git a/apps/product/urls/common.py b/apps/product/urls/common.py index f4eaaaac..bd6c331d 100644 --- a/apps/product/urls/common.py +++ b/apps/product/urls/common.py @@ -16,5 +16,4 @@ urlpatterns = [ name='create-comment'), path('slug//comments//', views.ProductCommentRUDView.as_view(), name='rud-comment'), - ] diff --git a/apps/product/views/__init__.py b/apps/product/views/__init__.py index 6f4a8001..d1a35297 100644 --- a/apps/product/views/__init__.py +++ b/apps/product/views/__init__.py @@ -1,4 +1,4 @@ -from .back import * from .common import * +from .back import * from .mobile import * from .web import * diff --git a/apps/product/views/back.py b/apps/product/views/back.py index 473daa0c..cb94d3aa 100644 --- a/apps/product/views/back.py +++ b/apps/product/views/back.py @@ -1,21 +1,17 @@ """Product app back-office views.""" -from django.conf import settings -from django.db.transaction import on_commit from django.shortcuts import get_object_or_404 from rest_framework import generics, status, permissions, views from rest_framework.response import Response -from gallery.tasks import delete_image from product import serializers, models +from product.views import ProductBaseView from utils.views import CreateDestroyGalleryViewMixin -class ProductBackOfficeMixinView: +class ProductBackOfficeMixinView(ProductBaseView): """Product back-office mixin view.""" permission_classes = (permissions.IsAuthenticated,) - queryset = models.Product.objects.with_base_related() \ - .order_by('-created', ) class ProductTypeBackOfficeMixinView: @@ -94,13 +90,15 @@ class ProductListCreateBackOfficeView(BackOfficeListCreateMixin, ProductBackOffi serializer_class = serializers.ProductBackOfficeDetailSerializer -class ProductTypeListCreateBackOfficeView(BackOfficeListCreateMixin, ProductTypeBackOfficeMixinView, +class ProductTypeListCreateBackOfficeView(BackOfficeListCreateMixin, + ProductTypeBackOfficeMixinView, generics.ListCreateAPIView): """Product type back-office list-create view.""" serializer_class = serializers.ProductTypeBackOfficeDetailSerializer -class ProductTypeRUDBackOfficeView(BackOfficeListCreateMixin, ProductTypeBackOfficeMixinView, +class ProductTypeRUDBackOfficeView(BackOfficeListCreateMixin, + ProductTypeBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """Product type back-office retrieve-update-destroy view.""" serializer_class = serializers.ProductTypeBackOfficeDetailSerializer @@ -115,3 +113,16 @@ class ProductTypeTagCategoryCreateBackOfficeView(ProductTypeBackOfficeMixinView, super().create(request, *args, **kwargs) return Response(status=status.HTTP_201_CREATED) + +class ProductSubTypeListCreateBackOfficeView(BackOfficeListCreateMixin, + ProductSubTypeBackOfficeMixinView, + generics.ListCreateAPIView): + """Product sub type back-office list-create view.""" + serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer + + +class ProductSubTypeRUDBackOfficeView(BackOfficeListCreateMixin, + ProductSubTypeBackOfficeMixinView, + generics.RetrieveUpdateDestroyAPIView): + """Product sub type back-office retrieve-update-destroy view.""" + serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer diff --git a/apps/product/views/common.py b/apps/product/views/common.py index 7a537f6e..e8f3a966 100644 --- a/apps/product/views/common.py +++ b/apps/product/views/common.py @@ -14,7 +14,10 @@ class ProductBaseView(generics.GenericAPIView): def get_queryset(self): """Override get_queryset method.""" - return Product.objects.with_base_related() + return Product.objects.published() \ + .with_base_related() \ + .by_country_code(self.request.country_code) \ + .order_by('-created') class ProductListView(ProductBaseView, generics.ListAPIView): diff --git a/apps/tag/serializers.py b/apps/tag/serializers.py index d6b851ab..02f2e4d3 100644 --- a/apps/tag/serializers.py +++ b/apps/tag/serializers.py @@ -13,7 +13,6 @@ class TagBaseSerializer(serializers.ModelSerializer): """Serializer for model Tag.""" label_translated = TranslatedField() - # label_translated = serializers.CharField(source='value', read_only=True, allow_null=True) index_name = serializers.CharField(source='value', read_only=True, allow_null=True) class Meta: @@ -57,6 +56,21 @@ class TagCategoryBaseSerializer(serializers.ModelSerializer): ) +class TagCategoryShortSerializer(serializers.ModelSerializer): + """Serializer for model TagCategory.""" + + label_translated = TranslatedField() + value_type_display = serializers.CharField(source='get_value_type_display', + read_only=True) + + class Meta(TagCategoryBaseSerializer.Meta): + """Meta class.""" + fields = [ + 'label_translated', + 'value_type_display', + ] + + class TagCategoryBackOfficeDetailSerializer(TagCategoryBaseSerializer): """Tag Category detail serializer for back-office users."""