added gallery to model product
This commit is contained in:
parent
efb468f00d
commit
8a49a5ee72
|
|
@ -17,7 +17,6 @@ def transfer_establishment():
|
||||||
old_establishments = Establishments.objects.exclude(
|
old_establishments = Establishments.objects.exclude(
|
||||||
id__in=list(Establishment.objects.all().values_list('old_id', flat=True))
|
id__in=list(Establishment.objects.all().values_list('old_id', flat=True))
|
||||||
).exclude(
|
).exclude(
|
||||||
Q(type='Wineyard') |
|
|
||||||
Q(location__timezone__isnull=True),
|
Q(location__timezone__isnull=True),
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'establishmentinfos_set',
|
'establishmentinfos_set',
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ class Product(TranslatedFieldsMixin, BaseAttributes):
|
||||||
null=True, blank=True, default=None,
|
null=True, blank=True, default=None,
|
||||||
validators=[MinValueValidator(EARLIEST_VINTAGE_YEAR),
|
validators=[MinValueValidator(EARLIEST_VINTAGE_YEAR),
|
||||||
MaxValueValidator(LATEST_VINTAGE_YEAR)])
|
MaxValueValidator(LATEST_VINTAGE_YEAR)])
|
||||||
|
gallery = models.ManyToManyField('gallery.Image', through='ProductGallery')
|
||||||
|
|
||||||
objects = ProductManager.from_queryset(ProductQuerySet)()
|
objects = ProductManager.from_queryset(ProductQuerySet)()
|
||||||
|
|
||||||
|
|
@ -213,9 +214,9 @@ class Product(TranslatedFieldsMixin, BaseAttributes):
|
||||||
raise ValidationError(_('wine_region field must be specified.'))
|
raise ValidationError(_('wine_region field must be specified.'))
|
||||||
if not self.product_type.index_name == ProductType.WINE and self.wine_region:
|
if not self.product_type.index_name == ProductType.WINE and self.wine_region:
|
||||||
raise ValidationError(_('wine_region field must not be specified.'))
|
raise ValidationError(_('wine_region field must not be specified.'))
|
||||||
if (self.wine_region and self.wine_appellation) and \
|
# if (self.wine_region and self.wine_appellation) and \
|
||||||
self.wine_appellation not in self.wine_region.appellations.all():
|
# self.wine_appellation not in self.wine_region.appellations.all():
|
||||||
raise ValidationError(_('Wine appellation not exists in wine region.'))
|
# raise ValidationError(_('Wine appellation not exists in wine region.'))
|
||||||
|
|
||||||
|
|
||||||
class OnlineProductManager(ProductManager):
|
class OnlineProductManager(ProductManager):
|
||||||
|
|
@ -288,6 +289,35 @@ class ProductStandard(models.Model):
|
||||||
verbose_name = _('wine standard')
|
verbose_name = _('wine standard')
|
||||||
|
|
||||||
|
|
||||||
|
class ProductGalleryQuerySet(models.QuerySet):
|
||||||
|
"""QuerySet for model Product"""
|
||||||
|
|
||||||
|
def main_image(self):
|
||||||
|
"""Return objects with flag is_main is True"""
|
||||||
|
return self.filter(is_main=True)
|
||||||
|
|
||||||
|
|
||||||
|
class ProductGallery(models.Model):
|
||||||
|
product = models.ForeignKey(Product, null=True,
|
||||||
|
related_name='product_gallery',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('product'))
|
||||||
|
image = models.ForeignKey('gallery.Image', null=True,
|
||||||
|
related_name='product_gallery',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('gallery'))
|
||||||
|
is_main = models.BooleanField(default=False,
|
||||||
|
verbose_name=_('Is the main image'))
|
||||||
|
|
||||||
|
objects = ProductGalleryQuerySet.as_manager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""ProductGallery meta class."""
|
||||||
|
verbose_name = _('product gallery')
|
||||||
|
verbose_name_plural = _('product galleries')
|
||||||
|
unique_together = (('product', 'is_main'), ('product', 'image'))
|
||||||
|
|
||||||
|
|
||||||
class ProductClassificationType(models.Model):
|
class ProductClassificationType(models.Model):
|
||||||
"""Product classification type."""
|
"""Product classification type."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
from .common import *
|
from .common import *
|
||||||
from .web import *
|
from .web import *
|
||||||
from .mobile import *
|
from .mobile import *
|
||||||
|
from .back import *
|
||||||
|
|
|
||||||
44
apps/product/serializers/back.py
Normal file
44
apps/product/serializers/back.py
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
"""Product app back-office serializers."""
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from product import models
|
||||||
|
from gallery.models import Image
|
||||||
|
|
||||||
|
|
||||||
|
class ProductBackOfficeGallerySerializer(serializers.ModelSerializer):
|
||||||
|
"""Serializer class for model ProductGallery."""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class"""
|
||||||
|
|
||||||
|
model = models.ProductGallery
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'is_main',
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_request_kwargs(self):
|
||||||
|
"""Get url kwargs from request."""
|
||||||
|
return self.context.get('request').parser_context.get('kwargs')
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
"""Override validate method."""
|
||||||
|
product_pk = self.get_request_kwargs().get('pk')
|
||||||
|
image_id = self.get_request_kwargs().get('image_id')
|
||||||
|
|
||||||
|
product_qs = models.Product.objects.filter(pk=product_pk)
|
||||||
|
image_qs = Image.objects.filter(id=image_id)
|
||||||
|
|
||||||
|
if not product_qs.exists():
|
||||||
|
raise serializers.ValidationError({'detail': _('Product not found')})
|
||||||
|
if not image_qs.exists():
|
||||||
|
raise serializers.ValidationError({'detail': _('Image not found')})
|
||||||
|
|
||||||
|
product = product_qs.first()
|
||||||
|
image = image_qs.first()
|
||||||
|
|
||||||
|
attrs['product'] = product
|
||||||
|
attrs['image'] = image
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
|
@ -5,6 +5,7 @@ from product.models import Product, ProductSubType, ProductType
|
||||||
from utils import exceptions as utils_exceptions
|
from utils import exceptions as utils_exceptions
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from location.serializers import WineRegionBaseSerializer, CountrySimpleSerializer
|
from location.serializers import WineRegionBaseSerializer, CountrySimpleSerializer
|
||||||
|
from gallery.models import Image
|
||||||
|
|
||||||
|
|
||||||
class ProductSubTypeBaseSerializer(serializers.ModelSerializer):
|
class ProductSubTypeBaseSerializer(serializers.ModelSerializer):
|
||||||
|
|
@ -59,7 +60,7 @@ class ProductBaseSerializer(serializers.ModelSerializer):
|
||||||
'subtypes',
|
'subtypes',
|
||||||
'public_mark',
|
'public_mark',
|
||||||
'wine_region',
|
'wine_region',
|
||||||
'wine_appellation',
|
'standards',
|
||||||
'available_countries',
|
'available_countries',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -92,3 +93,75 @@ class ProductFavoritesCreateSerializer(FavoritesCreateSerializer):
|
||||||
'content_object': validated_data.pop('product')
|
'content_object': validated_data.pop('product')
|
||||||
})
|
})
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
|
||||||
|
# class CropImageSerializer(serializers.Serializer):
|
||||||
|
# """Serializer for crop images for News object."""
|
||||||
|
#
|
||||||
|
# preview_url = serializers.SerializerMethodField()
|
||||||
|
# promo_horizontal_web_url = serializers.SerializerMethodField()
|
||||||
|
# promo_horizontal_mobile_url = serializers.SerializerMethodField()
|
||||||
|
# tile_horizontal_web_url = serializers.SerializerMethodField()
|
||||||
|
# tile_horizontal_mobile_url = serializers.SerializerMethodField()
|
||||||
|
# tile_vertical_web_url = serializers.SerializerMethodField()
|
||||||
|
# highlight_vertical_web_url = serializers.SerializerMethodField()
|
||||||
|
# editor_web_url = serializers.SerializerMethodField()
|
||||||
|
# editor_mobile_url = serializers.SerializerMethodField()
|
||||||
|
#
|
||||||
|
# def get_preview_url(self, obj):
|
||||||
|
# """Get crop preview."""
|
||||||
|
# return obj.instance.get_image_url('news_preview')
|
||||||
|
#
|
||||||
|
# def get_promo_horizontal_web_url(self, obj):
|
||||||
|
# """Get crop promo_horizontal_web."""
|
||||||
|
# return obj.instance.get_image_url('news_promo_horizontal_web')
|
||||||
|
#
|
||||||
|
# def get_promo_horizontal_mobile_url(self, obj):
|
||||||
|
# """Get crop promo_horizontal_mobile."""
|
||||||
|
# return obj.instance.get_image_url('news_promo_horizontal_mobile')
|
||||||
|
#
|
||||||
|
# def get_tile_horizontal_web_url(self, obj):
|
||||||
|
# """Get crop tile_horizontal_web."""
|
||||||
|
# return obj.instance.get_image_url('news_tile_horizontal_web')
|
||||||
|
#
|
||||||
|
# def get_tile_horizontal_mobile_url(self, obj):
|
||||||
|
# """Get crop tile_horizontal_mobile."""
|
||||||
|
# return obj.instance.get_image_url('news_tile_horizontal_mobile')
|
||||||
|
#
|
||||||
|
# def get_tile_vertical_web_url(self, obj):
|
||||||
|
# """Get crop tile_vertical_web."""
|
||||||
|
# return obj.instance.get_image_url('news_tile_vertical_web')
|
||||||
|
#
|
||||||
|
# def get_highlight_vertical_web_url(self, obj):
|
||||||
|
# """Get crop highlight_vertical_web."""
|
||||||
|
# return obj.instance.get_image_url('news_highlight_vertical_web')
|
||||||
|
#
|
||||||
|
# def get_editor_web_url(self, obj):
|
||||||
|
# """Get crop editor_web."""
|
||||||
|
# return obj.instance.get_image_url('news_editor_web')
|
||||||
|
#
|
||||||
|
# def get_editor_mobile_url(self, obj):
|
||||||
|
# """Get crop editor_mobile."""
|
||||||
|
# return obj.instance.get_image_url('news_editor_mobile')
|
||||||
|
|
||||||
|
|
||||||
|
class ProductImageSerializer(serializers.ModelSerializer):
|
||||||
|
"""Serializer for returning crop images of product image."""
|
||||||
|
|
||||||
|
orientation_display = serializers.CharField(source='get_orientation_display',
|
||||||
|
read_only=True)
|
||||||
|
original_url = serializers.URLField(source='image.url')
|
||||||
|
# auto_crop_images = CropImageSerializer(source='image', allow_null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Image
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'title',
|
||||||
|
'orientation_display',
|
||||||
|
'original_url',
|
||||||
|
# 'auto_crop_images',
|
||||||
|
]
|
||||||
|
extra_kwargs = {
|
||||||
|
'orientation': {'write_only': True}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ def transfer_product():
|
||||||
pprint(f"transfer_product errors: {errors}")
|
pprint(f"transfer_product errors: {errors}")
|
||||||
|
|
||||||
|
|
||||||
def transfer_plates():
|
def transfer_plate():
|
||||||
queryset = transfer_models.Merchandise.objects.all()
|
queryset = transfer_models.Merchandise.objects.all()
|
||||||
serialized_data = product_serializers.PlateSerializer(
|
serialized_data = product_serializers.PlateSerializer(
|
||||||
data=list(queryset.values()),
|
data=list(queryset.values()),
|
||||||
|
|
@ -165,6 +165,19 @@ def transfer_plates():
|
||||||
pprint(f"transfer_plates errors: {errors}")
|
pprint(f"transfer_plates errors: {errors}")
|
||||||
|
|
||||||
|
|
||||||
|
def transfer_plate_image():
|
||||||
|
queryset = transfer_models.Merchandise.objects.all()
|
||||||
|
serialized_data = product_serializers.PlateImageSerializer(
|
||||||
|
data=list(queryset.values()),
|
||||||
|
many=True)
|
||||||
|
if serialized_data.is_valid():
|
||||||
|
serialized_data.save()
|
||||||
|
else:
|
||||||
|
errors = []
|
||||||
|
for d in serialized_data.errors: errors.append(d) if d else None
|
||||||
|
pprint(f"transfer_plates_images errors: {errors}")
|
||||||
|
|
||||||
|
|
||||||
data_types = {
|
data_types = {
|
||||||
"partner": [transfer_partner],
|
"partner": [transfer_partner],
|
||||||
"product_type": [
|
"product_type": [
|
||||||
|
|
@ -181,6 +194,7 @@ data_types = {
|
||||||
],
|
],
|
||||||
"product": [
|
"product": [
|
||||||
transfer_product,
|
transfer_product,
|
||||||
transfer_plates,
|
transfer_plate,
|
||||||
|
transfer_plate_image,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
"""Product backoffice url patterns."""
|
||||||
|
from django.urls import path
|
||||||
|
from product.urls.common import urlpatterns as common_urlpatterns
|
||||||
|
from product import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('<int:pk>/gallery/', views.ProductBackOfficeGalleryListView.as_view(),
|
||||||
|
name='gallery-list'),
|
||||||
|
path('<int:pk>/gallery/<int:image_id>/', views.ProductBackOfficeGalleryCreateDestroyView.as_view(),
|
||||||
|
name='gallery-create-destroy'),
|
||||||
|
]
|
||||||
|
|
||||||
|
urlpatterns.extend(common_urlpatterns)
|
||||||
|
|
@ -7,6 +7,7 @@ app_name = 'product'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.ProductListView.as_view(), name='list'),
|
path('', views.ProductListView.as_view(), name='list'),
|
||||||
|
path('slug/<slug:slug>', views.ProductDetailView.as_view(), name='detail'),
|
||||||
path('slug/<slug:slug>/favorites/', views.CreateFavoriteProductView.as_view(),
|
path('slug/<slug:slug>/favorites/', views.CreateFavoriteProductView.as_view(),
|
||||||
name='create-destroy-favorites')
|
name='create-destroy-favorites')
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
"""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
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from gallery.tasks import delete_image
|
||||||
|
from product import serializers, models
|
||||||
|
|
||||||
|
|
||||||
|
class ProductBackOfficeMixinView:
|
||||||
|
"""Product back-office mixin view."""
|
||||||
|
|
||||||
|
permission_classes = (permissions.IsAuthenticated,)
|
||||||
|
queryset = models.Product.objects.with_base_related() \
|
||||||
|
.order_by('-created', )
|
||||||
|
|
||||||
|
|
||||||
|
class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView,
|
||||||
|
generics.CreateAPIView,
|
||||||
|
generics.DestroyAPIView):
|
||||||
|
"""Resource for a create gallery for product for back-office users."""
|
||||||
|
serializer_class = serializers.ProductBackOfficeGallerySerializer
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""
|
||||||
|
Returns the object the view is displaying.
|
||||||
|
"""
|
||||||
|
product_qs = self.filter_queryset(self.get_queryset())
|
||||||
|
|
||||||
|
product = get_object_or_404(product_qs, pk=self.kwargs['pk'])
|
||||||
|
gallery = get_object_or_404(product.product_gallery, image_id=self.kwargs['image_id'])
|
||||||
|
|
||||||
|
# May raise a permission denied
|
||||||
|
self.check_object_permissions(self.request, gallery)
|
||||||
|
|
||||||
|
return gallery
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
"""Overridden create method"""
|
||||||
|
super().create(request, *args, **kwargs)
|
||||||
|
return Response(status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
def destroy(self, request, *args, **kwargs):
|
||||||
|
"""Override destroy method."""
|
||||||
|
gallery_obj = self.get_object()
|
||||||
|
if settings.USE_CELERY:
|
||||||
|
on_commit(lambda: delete_image.delay(image_id=gallery_obj.image.id,
|
||||||
|
completely=False))
|
||||||
|
else:
|
||||||
|
on_commit(lambda: delete_image(image_id=gallery_obj.image.id,
|
||||||
|
completely=False))
|
||||||
|
# Delete an instances of ProductGallery model
|
||||||
|
gallery_obj.delete()
|
||||||
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
class ProductBackOfficeGalleryListView(ProductBackOfficeMixinView, generics.ListAPIView):
|
||||||
|
"""Resource for returning gallery for product for back-office users."""
|
||||||
|
serializer_class = serializers.ProductImageSerializer
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""Override get_object method."""
|
||||||
|
qs = super(ProductBackOfficeGalleryListView, self).get_queryset()
|
||||||
|
product = get_object_or_404(qs, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
|
# May raise a permission denied
|
||||||
|
self.check_object_permissions(self.request, product)
|
||||||
|
|
||||||
|
return product
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Override get_queryset method."""
|
||||||
|
return self.get_object().gallery.all()
|
||||||
|
|
@ -8,6 +8,7 @@ from product import filters
|
||||||
|
|
||||||
class ProductBaseView(generics.GenericAPIView):
|
class ProductBaseView(generics.GenericAPIView):
|
||||||
"""Product base view"""
|
"""Product base view"""
|
||||||
|
permission_classes = (permissions.AllowAny, )
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method."""
|
"""Override get_queryset method."""
|
||||||
|
|
@ -16,11 +17,16 @@ class ProductBaseView(generics.GenericAPIView):
|
||||||
|
|
||||||
class ProductListView(ProductBaseView, generics.ListAPIView):
|
class ProductListView(ProductBaseView, generics.ListAPIView):
|
||||||
"""List view for model Product."""
|
"""List view for model Product."""
|
||||||
permission_classes = (permissions.AllowAny, )
|
|
||||||
serializer_class = serializers.ProductBaseSerializer
|
serializer_class = serializers.ProductBaseSerializer
|
||||||
filter_class = filters.ProductFilterSet
|
filter_class = filters.ProductFilterSet
|
||||||
|
|
||||||
|
|
||||||
|
class ProductDetailView(ProductBaseView, generics.RetrieveAPIView):
|
||||||
|
"""Detail view fro model Product."""
|
||||||
|
lookup_field = 'slug'
|
||||||
|
serializer_class = serializers.ProductBaseSerializer
|
||||||
|
|
||||||
|
|
||||||
class CreateFavoriteProductView(generics.CreateAPIView,
|
class CreateFavoriteProductView(generics.CreateAPIView,
|
||||||
generics.DestroyAPIView):
|
generics.DestroyAPIView):
|
||||||
"""View for create/destroy product in favorites."""
|
"""View for create/destroy product in favorites."""
|
||||||
|
|
|
||||||
|
|
@ -1041,3 +1041,7 @@ class Merchandise(MigrateMixin):
|
||||||
highlighted = models.CharField(max_length=255)
|
highlighted = models.CharField(max_length=255)
|
||||||
site = models.ForeignKey('Sites', models.DO_NOTHING)
|
site = models.ForeignKey('Sites', models.DO_NOTHING)
|
||||||
attachment_suffix_url = models.CharField(max_length=255)
|
attachment_suffix_url = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'merchandises'
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
|
from django.conf import settings
|
||||||
from django.core.exceptions import MultipleObjectsReturned, ValidationError
|
from django.core.exceptions import MultipleObjectsReturned, ValidationError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from establishment.models import Establishment, ContactEmail, ContactPhone, EstablishmentType
|
from establishment.models import Establishment, ContactEmail, ContactPhone, EstablishmentType, \
|
||||||
|
EstablishmentSubType
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
from timetable.models import Timetable
|
from timetable.models import Timetable
|
||||||
from utils.legacy_parser import parse_legacy_schedule_content
|
from utils.legacy_parser import parse_legacy_schedule_content
|
||||||
from utils.serializers import TimeZoneChoiceField
|
from utils.serializers import TimeZoneChoiceField
|
||||||
from utils.slug_generator import generate_unique_slug
|
from utils.slug_generator import generate_unique_slug
|
||||||
|
from django.utils.text import slugify
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentSerializer(serializers.ModelSerializer):
|
class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
|
|
@ -53,14 +56,16 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
|
old_type = data.pop('type', None)
|
||||||
|
|
||||||
data.update({
|
data.update({
|
||||||
'slug': generate_unique_slug(Establishment, data['slug'] if data['slug'] else data['name']),
|
'slug': generate_unique_slug(Establishment, data['slug'] if data['slug'] else data['name']),
|
||||||
'address_id': self.get_address(data['location']),
|
'address_id': self.get_address(data['location']),
|
||||||
'establishment_type_id': self.get_type(data),
|
'establishment_type_id': self.get_type(old_type),
|
||||||
'is_publish': data.get('state') == 'published',
|
'is_publish': data.get('state') == 'published',
|
||||||
|
'subtype': self.get_subtype(old_type),
|
||||||
})
|
})
|
||||||
data.pop('location')
|
data.pop('location')
|
||||||
data.pop('type')
|
|
||||||
data.pop('state')
|
data.pop('state')
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
@ -69,6 +74,7 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
email = validated_data.pop('email')
|
email = validated_data.pop('email')
|
||||||
phone = validated_data.pop('phone')
|
phone = validated_data.pop('phone')
|
||||||
schedules = validated_data.pop('schedules')
|
schedules = validated_data.pop('schedules')
|
||||||
|
subtypes = [validated_data.pop('subtype', None)]
|
||||||
|
|
||||||
establishment = Establishment.objects.create(**validated_data)
|
establishment = Establishment.objects.create(**validated_data)
|
||||||
if email:
|
if email:
|
||||||
|
|
@ -86,6 +92,8 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
for schedule in new_schedules:
|
for schedule in new_schedules:
|
||||||
establishment.schedule.add(schedule)
|
establishment.schedule.add(schedule)
|
||||||
establishment.save()
|
establishment.save()
|
||||||
|
if subtypes:
|
||||||
|
establishment.establishment_subtypes.add(*[i for i in subtypes if i])
|
||||||
|
|
||||||
return establishment
|
return establishment
|
||||||
|
|
||||||
|
|
@ -97,12 +105,20 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_type(data):
|
def get_type(old_type):
|
||||||
types = {
|
types = {
|
||||||
'Restaurant': EstablishmentType.RESTAURANT,
|
'Restaurant': EstablishmentType.RESTAURANT,
|
||||||
'Shop': EstablishmentType.ARTISAN,
|
'Shop': EstablishmentType.ARTISAN,
|
||||||
|
'Producer': EstablishmentType.PRODUCER,
|
||||||
}
|
}
|
||||||
obj, _ = EstablishmentType.objects.get_or_create(index_name=types[data['type']])
|
if old_type == 'Wineyard':
|
||||||
|
index_name = types['Producer']
|
||||||
|
elif old_type in types.keys():
|
||||||
|
index_name = types[old_type]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
obj, _ = EstablishmentType.objects.get_or_create(index_name=index_name)
|
||||||
return obj.id
|
return obj.id
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -152,3 +168,13 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
result.append(obj)
|
result.append(obj)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_subtype(self, old_type):
|
||||||
|
if old_type == 'Wineyard':
|
||||||
|
subtype_name = 'Winery'
|
||||||
|
establishment_type_id = self.get_type(old_type)
|
||||||
|
subtype, _ = EstablishmentSubType.objects.get_or_create(
|
||||||
|
name={settings.FALLBACK_LOCALE: subtype_name},
|
||||||
|
index_name=slugify(subtype_name),
|
||||||
|
establishment_type_id=establishment_type_id)
|
||||||
|
return subtype
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from utils.methods import get_point_from_coordinates
|
||||||
from transfer.mixins import TransferSerializerMixin
|
from transfer.mixins import TransferSerializerMixin
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
from gallery.models import Image
|
||||||
|
|
||||||
|
|
||||||
class WineColorSerializer(TransferSerializerMixin):
|
class WineColorSerializer(TransferSerializerMixin):
|
||||||
|
|
@ -458,6 +459,7 @@ class PlateSerializer(TransferSerializerMixin):
|
||||||
attrs['old_id'] = attrs.pop('id')
|
attrs['old_id'] = attrs.pop('id')
|
||||||
attrs['vintage'] = self.get_vintage_year(attrs.pop('vintage'))
|
attrs['vintage'] = self.get_vintage_year(attrs.pop('vintage'))
|
||||||
attrs['product_type'] = product_type
|
attrs['product_type'] = product_type
|
||||||
|
attrs['state'] = self.Meta.model.PUBLISHED
|
||||||
attrs['subtype'] = self.get_product_sub_type(product_type,
|
attrs['subtype'] = self.get_product_sub_type(product_type,
|
||||||
self.PRODUCT_SUB_TYPE_INDEX_NAME)
|
self.PRODUCT_SUB_TYPE_INDEX_NAME)
|
||||||
return attrs
|
return attrs
|
||||||
|
|
@ -475,3 +477,42 @@ class PlateSerializer(TransferSerializerMixin):
|
||||||
# adding classification
|
# adding classification
|
||||||
obj.subtypes.add(*[i for i in subtypes if i])
|
obj.subtypes.add(*[i for i in subtypes if i])
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class PlateImageSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
id = serializers.IntegerField()
|
||||||
|
name = serializers.CharField()
|
||||||
|
attachment_suffix_url = serializers.CharField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.ProductGallery
|
||||||
|
fields = (
|
||||||
|
'id',
|
||||||
|
'attachment_suffix_url',
|
||||||
|
)
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
image = self.get_image(validated_data.pop('attachment_suffix_url', None),
|
||||||
|
validated_data.pop('name', None))
|
||||||
|
product = self.get_product(validated_data.pop('id'))
|
||||||
|
|
||||||
|
if product and image:
|
||||||
|
obj, created = models.ProductGallery.objects.get_or_create(
|
||||||
|
product=product,
|
||||||
|
image=image,
|
||||||
|
is_main=True)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def get_image(self, image_url, name):
|
||||||
|
if image_url:
|
||||||
|
obj, created = Image.objects.get_or_create(
|
||||||
|
title=name,
|
||||||
|
image=image_url)
|
||||||
|
return obj if created else None
|
||||||
|
|
||||||
|
def get_product(self, product_id):
|
||||||
|
if product_id:
|
||||||
|
product_qs = models.Product.objects.filter(old_id=product_id)
|
||||||
|
if product_qs.exists():
|
||||||
|
return product_qs.first()
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,6 @@ urlpatterns = [
|
||||||
path('news/', include('news.urls.back')),
|
path('news/', include('news.urls.back')),
|
||||||
path('review/', include('review.urls.back')),
|
path('review/', include('review.urls.back')),
|
||||||
path('tags/', include(('tag.urls.back', 'tag'), namespace='tag')),
|
path('tags/', include(('tag.urls.back', 'tag'), namespace='tag')),
|
||||||
|
path('products/', include(('product.urls.back', 'product'), namespace='product')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user