From e41b539ed71cd85bfdde57be38319bf49581a5c5 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Sun, 27 Oct 2019 18:42:51 +0300 Subject: [PATCH] added wine region --- apps/location/admin.py | 10 +++++++ apps/location/models.py | 43 +++++++++++++++++++++++++++++ apps/location/serializers/common.py | 30 ++++++++++++++++++++ apps/product/models.py | 11 ++++++++ apps/product/serializers/common.py | 3 ++ 5 files changed, 97 insertions(+) diff --git a/apps/location/admin.py b/apps/location/admin.py index a7610a65..adb355ac 100644 --- a/apps/location/admin.py +++ b/apps/location/admin.py @@ -19,6 +19,16 @@ class CityAdmin(admin.ModelAdmin): """City admin.""" +@admin.register(models.WineRegion) +class WineRegionAdmin(admin.ModelAdmin): + """WineRegion admin.""" + + +@admin.register(models.WineAppellation) +class WineAppellationAdmin(admin.ModelAdmin): + """WineAppellation admin.""" + + @admin.register(models.Address) class AddressAdmin(admin.OSMGeoAdmin): """Address admin.""" diff --git a/apps/location/models.py b/apps/location/models.py index da645de6..ba171c27 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -131,6 +131,49 @@ class Address(models.Model): return self.city.country_id +class WineRegionQuerySet(models.QuerySet): + """Wine region queryset.""" + + +class WineRegion(TranslatedFieldsMixin, models.Model): + """Wine region model.""" + STR_FIELD_NAME = 'name' + + name = TJSONField(verbose_name=_('Name'), + help_text='{"en-GB":"some text"}') + country = models.ForeignKey(Country, on_delete=models.PROTECT, + verbose_name=_('country')) + + objects = WineRegionQuerySet.as_manager() + + class Meta: + """Meta class.""" + verbose_name_plural = _('wine regions') + verbose_name = _('wine region') + + +class WineAppellationQuerySet(models.QuerySet): + """Wine appellation queryset.""" + + +class WineAppellation(TranslatedFieldsMixin, models.Model): + """Wine appellation model.""" + STR_FIELD_NAME = 'name' + + name = TJSONField(verbose_name=_('Name'), + help_text='{"en-GB":"some text"}') + wine_region = models.ForeignKey(WineRegion, on_delete=models.PROTECT, + related_name='appellations', + verbose_name=_('wine region')) + + objects = WineAppellationQuerySet.as_manager() + + class Meta: + """Meta class.""" + verbose_name_plural = _('wine appellations') + verbose_name = _('wine appellation') + + # todo: Make recalculate price levels @receiver(post_save, sender=Country) def run_recalculate_price_levels(sender, instance, **kwargs): diff --git a/apps/location/serializers/common.py b/apps/location/serializers/common.py index 87d0df4e..cfc14355 100644 --- a/apps/location/serializers/common.py +++ b/apps/location/serializers/common.py @@ -148,3 +148,33 @@ class AddressDetailSerializer(AddressBaseSerializer): 'city_id', 'city', ) + + +class WineAppellationBaseSerializer(serializers.ModelSerializer): + """Wine appellations.""" + name_translated = TranslatedField() + + class Meta: + """Meta class.""" + model = models.WineAppellation + fields = [ + 'id', + 'name_translated', + ] + + +class WineRegionBaseSerializer(serializers.ModelSerializer): + """Wine region serializer.""" + name_translated = TranslatedField() + country = CountrySerializer() + appellations = WineAppellationBaseSerializer(many=True) + + class Meta: + """Meta class.""" + model = models.WineRegion + fields = [ + 'id', + 'name_translated', + 'country', + 'appellations', + ] diff --git a/apps/product/models.py b/apps/product/models.py index d629d663..2f65c16a 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -134,6 +134,10 @@ class Product(TranslatedFieldsMixin, BaseAttributes): verbose_name=_('establishment')) public_mark = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('public mark'),) + wine_region = models.ForeignKey('location.WineRegion', on_delete=models.PROTECT, + related_name='wines', + blank=True, null=True, + verbose_name=_('wine region')) objects = ProductManager.from_queryset(ProductQuerySet)() @@ -143,6 +147,13 @@ class Product(TranslatedFieldsMixin, BaseAttributes): verbose_name = _('Product') verbose_name_plural = _('Products') + def clean_fields(self, exclude=None): + super().clean_fields(exclude=exclude) + if self.product_type.index_name == ProductType.WINE and not self.wine_region: + raise ValidationError(_('wine_region field must be specified.')) + if not self.product_type.index_name == ProductType.WINE and self.wine_region: + raise ValidationError(_('wine_region field must not be specified.')) + class OnlineProductManager(ProductManager): """Extended manger for OnlineProduct model.""" diff --git a/apps/product/serializers/common.py b/apps/product/serializers/common.py index f4f02b4d..c0a8c6ed 100644 --- a/apps/product/serializers/common.py +++ b/apps/product/serializers/common.py @@ -2,6 +2,7 @@ from rest_framework import serializers from utils.serializers import TranslatedField from product.models import Product, ProductSubType, ProductType +from location.serializers import WineRegionBaseSerializer class ProductSubTypeBaseSerializer(serializers.ModelSerializer): @@ -39,6 +40,7 @@ class ProductBaseSerializer(serializers.ModelSerializer): category_display = serializers.CharField(source='get_category_display') product_type = ProductTypeBaseSerializer() subtypes = ProductSubTypeBaseSerializer(many=True) + wine_region = WineRegionBaseSerializer(allow_null=True) class Meta: """Meta class.""" @@ -52,4 +54,5 @@ class ProductBaseSerializer(serializers.ModelSerializer): 'product_type', 'subtypes', 'public_mark', + 'wine_region', ]