diff --git a/apps/establishment/admin.py b/apps/establishment/admin.py index a40475b0..1f200f41 100644 --- a/apps/establishment/admin.py +++ b/apps/establishment/admin.py @@ -82,10 +82,15 @@ class MenuAdmin(admin.ModelAdmin): @admin.register(models.EstablishmentTypeTagCategory) -class EstablishmentTypeTagCategory(admin.ModelAdmin): +class EstablishmentTypeTagCategoryAdmin(admin.ModelAdmin): + """EstablishmentTypeTagCategory admin.""" + + +@admin.register(models.EstablishmentSubTypeTagCategory) +class EstablishmentSubTypeTagCategoryAdmin(admin.ModelAdmin): """EstablishmentTypeTagCategory admin.""" @admin.register(models.EstablishmentTag) -class EstablishmentTag(admin.ModelAdmin): +class EstablishmentTagAdmin(admin.ModelAdmin): """EstablishmentTag admin.""" diff --git a/apps/establishment/migrations/0035_establishmentsubtypetagcategory.py b/apps/establishment/migrations/0035_establishmentsubtypetagcategory.py new file mode 100644 index 00000000..6a85fca7 --- /dev/null +++ b/apps/establishment/migrations/0035_establishmentsubtypetagcategory.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.4 on 2019-10-11 10:47 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tag', '0002_auto_20191009_1408'), + ('establishment', '0034_merge_20191009_1457'), + ] + + operations = [ + migrations.CreateModel( + name='EstablishmentSubTypeTagCategory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('establishment_subtype', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tag_categories', to='establishment.EstablishmentSubType', verbose_name='establishment subtype')), + ('tag_category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='est_subtype_tag_categories', to='tag.TagCategory', verbose_name='tag category')), + ], + options={ + 'verbose_name': 'establishment subtype tag categories', + 'verbose_name_plural': 'establishment subtype tag categories', + }, + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index c248ca5d..39b750fa 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -589,7 +589,6 @@ class EstablishmentTypeTagCategoryQuerySet(models.QuerySet): def with_base_related(self): """Return with related relations.""" - # return self.select_related('tags', 'establishment_type') return self.select_related('establishment_type', 'tag_category') @@ -610,22 +609,26 @@ class EstablishmentTypeTagCategory(models.Model): verbose_name_plural = _('establishment type tag categories') -# class EstablishmentSubTypeTagCategoryQuerySet(models.QuerySet): -# """QuerySet for tag categories based on establishment subtype.""" -# -# -# class EstablishmentSubTypeTagCategory(models.Model): -# """Tag categories based on establishment subtype.""" -# establishment_subtype = models.ForeignKey(EstablishmentSubType, -# on_delete=models.CASCADE, -# related_name='tag_categories', -# verbose_name=_('establishment subtype')) -# tag_category = models.ForeignKey('tag.TagCategory', -# on_delete=models.CASCADE, -# related_name='est_subtype_tag_categories', -# verbose_name=_('tag category')) -# objects = EstablishmentSubTypeTagCategoryQuerySet.as_manager() -# -# class Meta: -# verbose_name = _('establishment subtype tag categories') -# verbose_name_plural = _('establishment subtype tag categories') +class EstablishmentSubTypeTagCategoryQuerySet(models.QuerySet): + """QuerySet for tag categories based on establishment subtype.""" + + def with_base_related(self): + """Return queryset with base related.""" + return self.select_related('establishment_subtype', 'tag_category') + + +class EstablishmentSubTypeTagCategory(models.Model): + """Tag categories based on establishment subtype.""" + establishment_subtype = models.ForeignKey(EstablishmentSubType, + on_delete=models.CASCADE, + related_name='tag_categories', + verbose_name=_('establishment subtype')) + tag_category = models.ForeignKey('tag.TagCategory', + on_delete=models.CASCADE, + related_name='est_subtype_tag_categories', + verbose_name=_('tag category')) + objects = EstablishmentSubTypeTagCategoryQuerySet.as_manager() + + class Meta: + verbose_name = _('establishment subtype tag categories') + verbose_name_plural = _('establishment subtype tag categories') diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 33d2e812..e164b44a 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -4,7 +4,7 @@ from establishment import models from establishment.serializers import ( EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer, ContactPhonesSerializer, SocialNetworkRelatedSerializers, - EstablishmentTypeSerializer) + EstablishmentTypeBaseSerializer) from main.models import Currency from utils.decorators import with_base_attributes @@ -20,7 +20,7 @@ class EstablishmentListCreateSerializer(EstablishmentBaseSerializer): emails = ContactEmailsSerializer(read_only=True, many=True, ) socials = SocialNetworkRelatedSerializers(read_only=True, many=True, ) slug = serializers.SlugField(required=True, allow_blank=False, max_length=50) - type = EstablishmentTypeSerializer(source='establishment_type', read_only=True) + type = EstablishmentTypeBaseSerializer(source='establishment_type', read_only=True) class Meta: model = models.Establishment @@ -54,7 +54,7 @@ class EstablishmentRUDSerializer(EstablishmentBaseSerializer): phones = ContactPhonesSerializer(read_only=False, many=True, ) emails = ContactEmailsSerializer(read_only=False, many=True, ) socials = SocialNetworkRelatedSerializers(read_only=False, many=True, ) - type = EstablishmentTypeSerializer(source='establishment_type') + type = EstablishmentTypeBaseSerializer(source='establishment_type') class Meta: model = models.Establishment diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index ef21e4fb..eec51466 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -89,6 +89,57 @@ class MenuRUDSerializers(ProjectModelSerializer): ] +class ReviewSerializer(serializers.ModelSerializer): + """Serializer for model Review.""" + text_translated = serializers.CharField(read_only=True) + + class Meta: + """Meta class.""" + model = review_models.Review + fields = ( + 'text_translated', + ) + + +class EstablishmentTypeBaseSerializer(serializers.ModelSerializer): + """Serializer for EstablishmentType model.""" + name_translated = TranslatedField() + + class Meta: + """Meta class.""" + model = models.EstablishmentType + fields = [ + 'id', + 'name', + 'name_translated', + 'use_subtypes' + ] + extra_kwargs = { + 'name': {'write_only': True}, + 'use_subtypes': {'write_only': True}, + } + + +class EstablishmentSubTypeBaseSerializer(serializers.ModelSerializer): + """Serializer for EstablishmentSubType models.""" + + name_translated = TranslatedField() + + class Meta: + """Meta class.""" + model = models.EstablishmentSubType + fields = [ + 'id', + 'name', + 'name_translated', + 'establishment_type' + ] + extra_kwargs = { + 'name': {'write_only': True}, + 'establishment_type': {'write_only': True} + } + + class EstablishmentTypeTagCategoryBaseSerializer(serializers.ModelSerializer): """Serializer for intermediate model EstablishmentTypeTagCategories.""" id = serializers.IntegerField(source='tag_category.id', read_only=True) @@ -119,71 +170,62 @@ class EstablishmentTypeTagCategoryBaseSerializer(serializers.ModelSerializer): return attrs -class EstablishmentTypeSerializer(serializers.ModelSerializer): - """Serializer for EstablishmentType model.""" - - name_translated = TranslatedField() +class EstablishmentSubTypeTagCategoryBaseSerializer(serializers.ModelSerializer): + """Serializer for intermediate model EstablishmentSubTypeTagCategories.""" + id = serializers.IntegerField(source='tag_category.id', read_only=True) + label_translated = TranslatedField(source='tag_category.label_translated') + tags = TagBaseSerializer(source='tag_category.tags', many=True, read_only=True) class Meta: """Meta class.""" - - model = models.EstablishmentType - fields = ('id', 'name', 'name_translated') + model = models.EstablishmentSubTypeTagCategory + fields = [ + 'id', + 'label_translated', + 'tags', + 'establishment_subtype', + 'tag_category', + ] extra_kwargs = { - 'name': {'write_only': True} + 'establishment_subtype': {'write_only': True}, + 'tag_category': {'write_only': True}, } + def validate(self, attrs): + """Override validate method.""" + if models.EstablishmentTypeTagCategory.objects.filter( + establishment_type=attrs.get('establishment_type'), + tag_category=attrs.get('tag_category')).exists(): + raise serializers.ValidationError(detail={'detail': _('Objects is already attached.')}) + return attrs -class EstablishmentSubTypeSerializer(serializers.ModelSerializer): - """Serializer for EstablishmentSubType models.""" - name_translated = TranslatedField() +class EstablishmentSubTypeSerializer(EstablishmentSubTypeBaseSerializer): + """Extended serializer for EstablishmentSubType model with tags.""" + tag_categories = EstablishmentSubTypeTagCategoryBaseSerializer(many=True, read_only=True) - class Meta: + class Meta(EstablishmentSubTypeBaseSerializer.Meta): + """Meta class""" + fields = [ + 'id', + 'name_translated', + 'tag_categories' + ] + + +class EstablishmentTagsByType(EstablishmentTypeBaseSerializer): + """Tags by establishment type""" + tag_categories = EstablishmentTypeTagCategoryBaseSerializer(many=True) + subtypes = EstablishmentSubTypeSerializer(many=True, source='establishmentsubtype_set') + + class Meta(EstablishmentTypeBaseSerializer.Meta): """Meta class.""" - - model = models.EstablishmentSubType - fields = ('id', 'name', 'name_translated', 'establishment_type') - extra_kwargs = { - 'name': {'write_only': True}, - 'establishment_type': {'write_only': True} - } - - -# class EstablishmentSubTypeTagCategoryBaseSerializer(serializers.ModelSerializer): -# """Serializer for intermediate model EstablishmentSubTypeTagCategories.""" -# -# class Meta: -# """Meta class.""" -# model = models.EstablishmentSubTypeTagCategory -# fields = [ -# 'establishment_subtype', -# 'tag_category', -# ] -# extra_kwargs = { -# 'establishment_subtype': {'write_only': True}, -# 'tag_category': {'write_only': True}, -# } -# -# def validate(self, attrs): -# """Override validate method.""" -# if models.EstablishmentSubTypeTagCategory.objects.filter( -# establishment_type=attrs.get('establishment_subtype'), -# tag_category=attrs.get('tag_category')).exists(): -# raise serializers.ValidationError(detail={'detail': _('Objects is already attached.')}) -# return attrs - - -class ReviewSerializer(serializers.ModelSerializer): - """Serializer for model Review.""" - text_translated = serializers.CharField(read_only=True) - - class Meta: - """Meta class.""" - model = review_models.Review - fields = ( - 'text_translated', - ) + fields = [ + 'id', + 'name_translated', + 'tag_categories', + 'subtypes', + ] class EstablishmentEmployeeSerializer(serializers.ModelSerializer): @@ -202,19 +244,6 @@ class EstablishmentEmployeeSerializer(serializers.ModelSerializer): fields = ('id', 'name', 'position_translated', 'awards', 'priority') -class EstablishmentCategoryTagListSerializer(serializers.ModelSerializer): - """Serializer for establishment category tags.""" - label_translated = TranslatedField() - - class Meta: - """Meta class.""" - model = tag_models.TagCategory - fields = [ - 'id', - 'label_translated', - ] - - class EstablishmentTagSerializer(serializers.ModelSerializer): """Serializer for intermediate model EstablishmentTag.""" id = serializers.IntegerField(source='tag.id') @@ -262,8 +291,8 @@ class EstablishmentDetailSerializer(EstablishmentBaseSerializer): description_translated = TranslatedField() image = serializers.URLField(source='image_url') - type = EstablishmentTypeSerializer(source='establishment_type', read_only=True) - subtypes = EstablishmentSubTypeSerializer(many=True, source='establishment_subtypes') + type = EstablishmentTypeBaseSerializer(source='establishment_type', read_only=True) + subtypes = EstablishmentSubTypeBaseSerializer(many=True, source='establishment_subtypes') awards = AwardSerializer(many=True) schedule = ScheduleRUDSerializer(many=True, allow_null=True) phones = ContactPhonesSerializer(read_only=True, many=True) @@ -396,3 +425,4 @@ class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer): 'content_object': validated_data.pop('establishment') }) return super().create(validated_data) + diff --git a/apps/establishment/urls/back.py b/apps/establishment/urls/back.py index ad10ea1a..e0489783 100644 --- a/apps/establishment/urls/back.py +++ b/apps/establishment/urls/back.py @@ -14,7 +14,7 @@ urlpatterns = [ name='schedule-rud'), path('/schedule/', views.EstablishmentScheduleCreateView.as_view(), name='schedule-create'), - path('/tags/categories/', views.EstablishmentTagCategoryListView.as_view(), + path('/tags/', views.EstablishmentTagCategoryListView.as_view(), name='tag-category-list'), path('menus/', views.MenuListCreateView.as_view(), name='menu-list'), path('menus//', views.MenuRUDView.as_view(), name='menu-rud'), @@ -34,6 +34,6 @@ urlpatterns = [ name='type-attach-tag-category'), path('subtypes/', views.EstablishmentSubtypeListCreateView.as_view(), name='subtype-list'), path('subtypes//', views.EstablishmentSubtypeRUDView.as_view(), name='subtype-rud'), - # path('subtypes/attach-tag-category/', views.EstablishmentSubTypeAttachTagCategoryView.as_view(), - # name='subtype-attach-tag-category'), + path('subtypes/attach-tag-category/', views.EstablishmentSubTypeAttachTagCategoryView.as_view(), + name='subtype-attach-tag-category'), ] \ No newline at end of file diff --git a/apps/establishment/views/back.py b/apps/establishment/views/back.py index 7d0949be..84855982 100644 --- a/apps/establishment/views/back.py +++ b/apps/establishment/views/back.py @@ -54,9 +54,9 @@ class EstablishmentScheduleCreateView(generics.CreateAPIView): serializer_class = ScheduleCreateSerializer -class EstablishmentTagCategoryListView(EstablishmentMixinViews, generics.ListAPIView): +class EstablishmentTagCategoryListView(EstablishmentMixinViews, generics.RetrieveAPIView): """View for establishment tag categories.""" - serializer_class = serializers.EstablishmentTypeTagCategoryBaseSerializer + serializer_class = serializers.EstablishmentTagsByType pagination_class = None def get_object(self): @@ -74,12 +74,7 @@ class EstablishmentTagCategoryListView(EstablishmentMixinViews, generics.ListAPI # May raise a permission denied self.check_object_permissions(self.request, obj) - return obj - - def get_queryset(self): - """Overridden get_queryset method.""" - establishment = self.get_object() - return establishment.establishment_type.tag_categories.all() + return obj.establishment_type class EstablishmentTypeAttachTagCategoryView(generics.CreateAPIView): @@ -96,17 +91,6 @@ class EstablishmentTypeAttachTagCategoryView(generics.CreateAPIView): return Response(status=status.HTTP_200_OK) -# class EstablishmentSubTypeAttachTagCategoryView(generics.CreateAPIView): -# """Attach tag category to establishment subtype.""" -# queryset = models.EstablishmentSubTypeTagCategory.objects.all() -# serializer_class = serializers.EstablishmentSubTypeTagCategoryBaseSerializer -# -# def post(self, request, *args, **kwargs): -# """Overridden post-method.""" -# super(EstablishmentSubTypeAttachTagCategoryView, self).post(request) -# return Response(status=status.HTTP_200_OK) - - class MenuListCreateView(generics.ListCreateAPIView): """Menu list create view.""" serializer_class = serializers.MenuSerializers @@ -186,31 +170,44 @@ class EmployeeRUDView(generics.RetrieveUpdateDestroyAPIView): class EstablishmentTypeListCreateView(generics.ListCreateAPIView): """Establishment type list/create view.""" - serializer_class = serializers.EstablishmentTypeSerializer + serializer_class = serializers.EstablishmentTypeBaseSerializer queryset = models.EstablishmentType.objects.all() pagination_class = None class EstablishmentTypeRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment type retrieve/update/destroy view.""" - serializer_class = serializers.EstablishmentTypeSerializer + serializer_class = serializers.EstablishmentTypeBaseSerializer queryset = models.EstablishmentType.objects.all() class EstablishmentSubtypeListCreateView(generics.ListCreateAPIView): """Establishment subtype list/create view.""" - serializer_class = serializers.EstablishmentSubTypeSerializer + serializer_class = serializers.EstablishmentSubTypeBaseSerializer queryset = models.EstablishmentSubType.objects.all() pagination_class = None class EstablishmentSubtypeRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment subtype retrieve/update/destroy view.""" - serializer_class = serializers.EstablishmentSubTypeSerializer + serializer_class = serializers.EstablishmentSubTypeBaseSerializer queryset = models.EstablishmentSubType.objects.all() -# todo: next task +class EstablishmentSubTypeAttachTagCategoryView(generics.CreateAPIView): + """Attach tag category to establishment subtype.""" + serializer_class = serializers.EstablishmentSubTypeTagCategoryBaseSerializer + + def get_queryset(self): + """Override get_queryset method.""" + return models.EstablishmentSubTypeTagCategory.objects.with_base_related() + + def post(self, request, *args, **kwargs): + """Overridden post-method.""" + super(EstablishmentSubTypeAttachTagCategoryView, self).post(request) + return Response(status=status.HTTP_200_OK) + + # class EstablishmentTagListCreateView(generics.CreateAPIView): # """Establishment tag list/create view.""" # serializer_class = serializers.EstablishmentTagCategoryListCreateSerializer diff --git a/apps/establishment/views/web.py b/apps/establishment/views/web.py index b4ef4f13..f164ec73 100644 --- a/apps/establishment/views/web.py +++ b/apps/establishment/views/web.py @@ -84,7 +84,7 @@ class EstablishmentTypeListView(generics.ListAPIView): """Resource for getting a list of establishment types.""" permission_classes = (permissions.AllowAny,) - serializer_class = serializers.EstablishmentTypeSerializer + serializer_class = serializers.EstablishmentTypeBaseSerializer queryset = models.EstablishmentType.objects.all()