From 60cdec99e02a9b0cbab04110517cebe4cfe80772 Mon Sep 17 00:00:00 2001 From: evgeniy-st Date: Tue, 15 Oct 2019 17:17:03 +0300 Subject: [PATCH] refactor tags --- apps/establishment/admin.py | 28 +-- .../migrations/0037_auto_20191015_1404.py | 54 +++++ apps/establishment/models.py | 202 ++++++++++-------- apps/establishment/serializers/back.py | 182 ++++++++-------- apps/establishment/serializers/common.py | 84 ++++---- apps/establishment/urls/back.py | 12 +- apps/establishment/urls/common.py | 2 +- apps/establishment/views/back.py | 70 +++--- apps/search_indexes/documents/news.py | 18 +- apps/tag/filters.py | 48 +++++ apps/tag/models.py | 12 +- apps/tag/serializers.py | 46 ++-- apps/tag/urls/__init__.py | 0 apps/tag/{urls.py => urls/back.py} | 10 +- apps/tag/urls/web.py | 16 ++ apps/tag/views.py | 28 ++- project/settings/base.py | 2 +- project/urls/back.py | 2 +- project/urls/web.py | 1 + 19 files changed, 494 insertions(+), 323 deletions(-) create mode 100644 apps/establishment/migrations/0037_auto_20191015_1404.py create mode 100644 apps/tag/filters.py create mode 100644 apps/tag/urls/__init__.py rename apps/tag/{urls.py => urls/back.py} (53%) create mode 100644 apps/tag/urls/web.py diff --git a/apps/establishment/admin.py b/apps/establishment/admin.py index 1f200f41..8a5e57de 100644 --- a/apps/establishment/admin.py +++ b/apps/establishment/admin.py @@ -80,17 +80,17 @@ class MenuAdmin(admin.ModelAdmin): category_translated.short_description = _('category') - -@admin.register(models.EstablishmentTypeTagCategory) -class EstablishmentTypeTagCategoryAdmin(admin.ModelAdmin): - """EstablishmentTypeTagCategory admin.""" - - -@admin.register(models.EstablishmentSubTypeTagCategory) -class EstablishmentSubTypeTagCategoryAdmin(admin.ModelAdmin): - """EstablishmentTypeTagCategory admin.""" - - -@admin.register(models.EstablishmentTag) -class EstablishmentTagAdmin(admin.ModelAdmin): - """EstablishmentTag admin.""" +# +# @admin.register(models.EstablishmentTypeTagCategory) +# class EstablishmentTypeTagCategoryAdmin(admin.ModelAdmin): +# """EstablishmentTypeTagCategory admin.""" +# +# +# @admin.register(models.EstablishmentSubTypeTagCategory) +# class EstablishmentSubTypeTagCategoryAdmin(admin.ModelAdmin): +# """EstablishmentTypeTagCategory admin.""" +# +# +# @admin.register(models.EstablishmentTag) +# class EstablishmentTagAdmin(admin.ModelAdmin): +# """EstablishmentTag admin.""" diff --git a/apps/establishment/migrations/0037_auto_20191015_1404.py b/apps/establishment/migrations/0037_auto_20191015_1404.py new file mode 100644 index 00000000..971970e2 --- /dev/null +++ b/apps/establishment/migrations/0037_auto_20191015_1404.py @@ -0,0 +1,54 @@ +# Generated by Django 2.2.4 on 2019-10-15 14:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tag', '0002_auto_20191009_1408'), + ('establishment', '0036_auto_20191011_1356'), + ] + + operations = [ + migrations.RemoveField( + model_name='establishmenttag', + name='establishment', + ), + migrations.RemoveField( + model_name='establishmenttag', + name='tag', + ), + migrations.RemoveField( + model_name='establishmenttypetagcategory', + name='establishment_type', + ), + migrations.RemoveField( + model_name='establishmenttypetagcategory', + name='tag_category', + ), + migrations.AddField( + model_name='establishment', + name='tags', + field=models.ManyToManyField(related_name='establishments', to='tag.Tag', verbose_name='Tag'), + ), + migrations.AddField( + model_name='establishmentsubtype', + name='tag_categories', + field=models.ManyToManyField(related_name='establishment_subtypes', to='tag.TagCategory', verbose_name='Tag'), + ), + migrations.AddField( + model_name='establishmenttype', + name='tag_categories', + field=models.ManyToManyField(related_name='establishment_types', to='tag.TagCategory', verbose_name='Tag'), + ), + migrations.DeleteModel( + name='EstablishmentSubTypeTagCategory', + ), + migrations.DeleteModel( + name='EstablishmentTag', + ), + migrations.DeleteModel( + name='EstablishmentTypeTagCategory', + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 195f029d..14d7e02b 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -27,15 +27,16 @@ class EstablishmentTypeQuerySet(models.QuerySet): def with_base_related(self): """Return QuerySet with base related.""" - return self.prefetch_related( - models.Prefetch('tag_categories', - EstablishmentTypeTagCategory.objects.select_related('tag_category')), - models.Prefetch('establishmentsubtype_set', - EstablishmentSubType.objects.prefetch_related( - models.Prefetch( - 'tag_categories', - EstablishmentSubTypeTagCategory.objects.select_related('tag_category')))) - ) + return self + # return self.prefetch_related( + # models.Prefetch('tag_categories', + # EstablishmentTypeTagCategory.objects.select_related('tag_category')), + # models.Prefetch('establishmentsubtype_set', + # EstablishmentSubType.objects.prefetch_related( + # models.Prefetch( + # 'tag_categories', + # EstablishmentSubTypeTagCategory.objects.select_related('tag_category')))) + # ) # todo: establishment type&subtypes check @@ -47,6 +48,9 @@ class EstablishmentType(TranslatedFieldsMixin, ProjectBaseMixin): name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), help_text='{"en-GB":"some text"}') use_subtypes = models.BooleanField(_('Use subtypes'), default=True) + tag_categories = models.ManyToManyField('tag.TagCategory', + related_name='establishment_types', + verbose_name=_('Tag')) objects = EstablishmentTypeQuerySet.as_manager() @@ -75,6 +79,9 @@ class EstablishmentSubType(ProjectBaseMixin, TranslatedFieldsMixin): establishment_type = models.ForeignKey(EstablishmentType, on_delete=models.CASCADE, verbose_name=_('Type')) + tag_categories = models.ManyToManyField('tag.TagCategory', + related_name='establishment_subtypes', + verbose_name=_('Tag')) objects = EstablishmentSubTypeManager() @@ -94,14 +101,15 @@ class EstablishmentQuerySet(models.QuerySet): def with_base_related(self): """Return qs with related objects.""" - return self.select_related('address', 'establishment_type').prefetch_related( - models.Prefetch('tags', - EstablishmentTag.objects.select_related('tag')), - models.Prefetch('establishment_type__tag_categories', - EstablishmentTypeTagCategory.objects.select_related('tag_category')), - models.Prefetch('establishment_type__establishmentsubtype_set', - EstablishmentSubType.objects.prefetch_related('tag_categories')), - ) + return self + # return self.select_related('address', 'establishment_type').prefetch_related( + # models.Prefetch('tags', + # EstablishmentTag.objects.select_related('tag')), + # models.Prefetch('establishment_type__tag_categories', + # EstablishmentTypeTagCategory.objects.select_related('tag_category')), + # models.Prefetch('establishment_type__establishmentsubtype_set', + # EstablishmentSubType.objects.prefetch_related('tag_categories')), + # ) def with_extended_related(self): return self.select_related('establishment_type').\ @@ -320,7 +328,11 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): verbose_name=_('Establishment slug'), editable=True) awards = generic.GenericRelation(to='main.Award', related_query_name='establishment') - tags = generic.GenericRelation(to='main.MetaDataContent') + # todo: remove after data merge + # tags = generic.GenericRelation(to='main.MetaDataContent') + tags = models.ManyToManyField('tag.Tag', related_name='establishments', + verbose_name=_('Tag')) + old_tags = generic.GenericRelation(to='main.MetaDataContent') reviews = generic.GenericRelation(to='review.Review') comments = generic.GenericRelation(to='comment.Comment') favorites = generic.GenericRelation(to='favorites.Favorites') @@ -575,81 +587,81 @@ class SocialNetwork(models.Model): def __str__(self): return self.title +# +# class EstablishmentTagQuerySet(models.QuerySet): +# """Establishment tag QuerySet.""" +# +# def by_country_code(self, code): +# """Return establishment tags by establishment country code.""" +# return self.filter(establishment__address__city__country__code=code) -class EstablishmentTagQuerySet(models.QuerySet): - """Establishment tag QuerySet.""" - - def by_country_code(self, code): - """Return establishment tags by establishment country code.""" - return self.filter(establishment__address__city__country__code=code) - - -class EstablishmentTag(models.Model): - """Establishment tag model.""" - tag = models.ForeignKey('tag.Tag', - on_delete=models.CASCADE, - related_name='tags', - verbose_name=_('tag')) - establishment = models.ForeignKey('establishment.Establishment', - on_delete=models.CASCADE, - related_name='tags', - verbose_name=_('establishment')) - objects = EstablishmentTagQuerySet.as_manager() - - class Meta: - verbose_name = _('establishment tag') - verbose_name_plural = _('establishment tags') - - -class EstablishmentTypeTagCategoryQuerySet(models.QuerySet): - """EstablishmentTypeTagCategory QuerySet.""" - - def by_country_code(self, code): - """Return establishment tags by country code""" - return self.filter(tag_category__country__code=code) - - def with_base_related(self): - """Return with related relations.""" - return self.select_related('establishment_type', 'tag_category') - - -class EstablishmentTypeTagCategory(models.Model): - """Tag categories based on establishment type.""" - establishment_type = models.ForeignKey(EstablishmentType, - on_delete=models.CASCADE, - related_name='tag_categories', - verbose_name=_('establishment type')) - tag_category = models.ForeignKey('tag.TagCategory', - on_delete=models.CASCADE, - related_name='est_type_tag_categories', - verbose_name=_('tag category')) - objects = EstablishmentTypeTagCategoryQuerySet.as_manager() - - class Meta: - verbose_name = _('establishment type tag categories') - verbose_name_plural = _('establishment type 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') +# +# class EstablishmentTag(models.Model): +# """Establishment tag model.""" +# tag = models.ForeignKey('tag.Tag', +# on_delete=models.CASCADE, +# related_name='tags', +# verbose_name=_('tag')) +# establishment = models.ForeignKey('establishment.Establishment', +# on_delete=models.CASCADE, +# related_name='tags', +# verbose_name=_('establishment')) +# objects = EstablishmentTagQuerySet.as_manager() +# +# class Meta: +# verbose_name = _('establishment tag') +# verbose_name_plural = _('establishment tags') +# +# +# class EstablishmentTypeTagCategoryQuerySet(models.QuerySet): +# """EstablishmentTypeTagCategory QuerySet.""" +# +# def by_country_code(self, code): +# """Return establishment tags by country code""" +# return self.filter(tag_category__country__code=code) +# +# def with_base_related(self): +# """Return with related relations.""" +# return self.select_related('establishment_type', 'tag_category') +# +# +# class EstablishmentTypeTagCategory(models.Model): +# """Tag categories based on establishment type.""" +# establishment_type = models.ForeignKey(EstablishmentType, +# on_delete=models.CASCADE, +# related_name='tag_categories', +# verbose_name=_('establishment type')) +# tag_category = models.ForeignKey('tag.TagCategory', +# on_delete=models.CASCADE, +# related_name='est_type_tag_categories', +# verbose_name=_('tag category')) +# objects = EstablishmentTypeTagCategoryQuerySet.as_manager() +# +# class Meta: +# verbose_name = _('establishment type tag categories') +# verbose_name_plural = _('establishment type 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 21f63e17..dca25763 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -5,8 +5,8 @@ from establishment import models from establishment.serializers import ( EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer, ContactPhonesSerializer, SocialNetworkRelatedSerializers, - EstablishmentTypeBaseSerializer, EstablishmentSubTypeBaseSerializer, - EstablishmentTypeTagCategoryBaseSerializer) + EstablishmentTypeBaseSerializer, EstablishmentSubTypeBaseSerializer) + # EstablishmentTypeTagCategoryBaseSerializer) from main.models import Currency from tag.serializers import TagBaseSerializer from utils.decorators import with_base_attributes @@ -146,94 +146,94 @@ class EmployeeBackSerializers(serializers.ModelSerializer): ] -class EstablishmentTagCreateSerializer(serializers.ModelSerializer): - """Serializer for model EstablishmentTag.""" - class Meta: - model = models.EstablishmentTag - fields = [ - 'tag', - 'establishment' - ] - extra_kwargs = { - 'tag': {'write_only': True}, - 'establishment': {'write_only': True}, - } - - def validate(self, attrs): - """Validate method.""" - establishment = attrs.get('establishment') - tag = attrs.get('tag') - - # Check if tag is already added to establishment. - if establishment.tags.filter(tag=tag).exists(): - raise serializers.ValidationError(detail={'detail': _('Tag is already added.')}) - - # Сhecking tag availability for establishment type. - if not establishment.establishment_type.use_subtypes: - qs = establishment.establishment_type.tag_categories.filter(tag_category=tag.category) - else: - # Сhecking tag availability for establishment subtype. - qs = establishment.establishment_type.tag_categories.filter( - establishmentsubtype_set__tag_category=tag.category) - if not qs.exists(): - raise serializers.ValidationError( - detail={'detail': _('Tag is not available for this establishment type|subtype.')}) - return attrs +# class EstablishmentTagCreateSerializer(serializers.ModelSerializer): +# """Serializer for model EstablishmentTag.""" +# class Meta: +# model = models.EstablishmentTag +# fields = [ +# 'tag', +# 'establishment' +# ] +# extra_kwargs = { +# 'tag': {'write_only': True}, +# 'establishment': {'write_only': True}, +# } +# +# def validate(self, attrs): +# """Validate method.""" +# establishment = attrs.get('establishment') +# tag = attrs.get('tag') +# +# # Check if tag is already added to establishment. +# if establishment.tags.filter(tag=tag).exists(): +# raise serializers.ValidationError(detail={'detail': _('Tag is already added.')}) +# +# # Сhecking tag availability for establishment type. +# if not establishment.establishment_type.use_subtypes: +# qs = establishment.establishment_type.tag_categories.filter(tag_category=tag.category) +# else: +# # Сhecking tag availability for establishment subtype. +# qs = establishment.establishment_type.tag_categories.filter( +# establishmentsubtype_set__tag_category=tag.category) +# if not qs.exists(): +# raise serializers.ValidationError( +# detail={'detail': _('Tag is not available for this establishment type|subtype.')}) +# return attrs -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.EstablishmentSubTypeTagCategory - fields = [ - 'id', - 'label_translated', - 'tags', - '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.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(EstablishmentSubTypeBaseSerializer): - """Extended serializer for EstablishmentSubType model with tags.""" - tag_categories = EstablishmentSubTypeTagCategoryBaseSerializer(many=True, read_only=True) - - 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.""" - fields = [ - 'id', - 'name_translated', - 'tag_categories', - 'subtypes', - ] +# 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.EstablishmentSubTypeTagCategory +# fields = [ +# 'id', +# 'label_translated', +# 'tags', +# '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.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(EstablishmentSubTypeBaseSerializer): +# """Extended serializer for EstablishmentSubType model with tags.""" +# tag_categories = EstablishmentSubTypeTagCategoryBaseSerializer(many=True, read_only=True) +# +# 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.""" +# fields = [ +# 'id', +# 'name_translated', +# 'tag_categories', +# 'subtypes', +# ] diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 1789da31..7c659c9b 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -139,34 +139,34 @@ class EstablishmentSubTypeBaseSerializer(serializers.ModelSerializer): } -class EstablishmentTypeTagCategoryBaseSerializer(serializers.ModelSerializer): - """Serializer for intermediate model EstablishmentTypeTagCategories.""" - 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.EstablishmentTypeTagCategory - fields = [ - 'id', - 'label_translated', - 'tags', - 'establishment_type', - 'tag_category', - ] - extra_kwargs = { - 'establishment_type': {'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 EstablishmentTypeTagCategoryBaseSerializer(serializers.ModelSerializer): +# """Serializer for intermediate model EstablishmentTypeTagCategories.""" +# 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.EstablishmentTypeTagCategory +# fields = [ +# 'id', +# 'label_translated', +# 'tags', +# 'establishment_type', +# 'tag_category', +# ] +# extra_kwargs = { +# 'establishment_type': {'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 EstablishmentEmployeeSerializer(serializers.ModelSerializer): @@ -184,19 +184,19 @@ class EstablishmentEmployeeSerializer(serializers.ModelSerializer): model = models.Employee fields = ('id', 'name', 'position_translated', 'awards', 'priority') - -class EstablishmentTagSerializer(serializers.ModelSerializer): - """Serializer for intermediate model EstablishmentTag.""" - id = serializers.IntegerField(source='tag.id') - label_translated = serializers.CharField(source='tag.label_translated') - - class Meta: - """Meta class.""" - model = models.EstablishmentTag - fields = [ - 'id', - 'label_translated' - ] +# +# class EstablishmentTagSerializer(serializers.ModelSerializer): +# """Serializer for intermediate model EstablishmentTag.""" +# id = serializers.IntegerField(source='tag.id') +# label_translated = serializers.CharField(source='tag.label_translated') +# +# class Meta: +# """Meta class.""" +# model = models.EstablishmentTag +# fields = [ +# 'id', +# 'label_translated' +# ] class EstablishmentBaseSerializer(ProjectModelSerializer): @@ -206,7 +206,7 @@ class EstablishmentBaseSerializer(ProjectModelSerializer): slug = serializers.SlugField(allow_blank=False, required=True, max_length=50) address = AddressBaseSerializer() in_favorites = serializers.BooleanField(allow_null=True) - tags = EstablishmentTagSerializer(many=True) + tags = TagBaseSerializer(read_only=True, many=True) class Meta: """Meta class.""" diff --git a/apps/establishment/urls/back.py b/apps/establishment/urls/back.py index 3db81dce..cdd4d183 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('attach-tag/', views.EstablishmentTagCreateView.as_view(), name='attach-tag'), + # path('attach-tag/', views.EstablishmentTagCreateView.as_view(), name='attach-tag'), path('menus/', views.MenuListCreateView.as_view(), name='menu-list'), path('menus//', views.MenuRUDView.as_view(), name='menu-rud'), path('plates/', views.PlateListCreateView.as_view(), name='plates'), @@ -28,12 +28,12 @@ urlpatterns = [ path('employees/', views.EmployeeListCreateView.as_view(), name='employees'), path('employees//', views.EmployeeRUDView.as_view(), name='employees-rud'), path('types/', views.EstablishmentTypeListCreateView.as_view(), name='type-list'), - path('types/tags/', views.EstablishmentTypeTagListView.as_view(), name='type-tag-list'), + # path('types/tags/', views.EstablishmentTypeTagListView.as_view(), name='type-tag-list'), path('types//', views.EstablishmentTypeRUDView.as_view(), name='type-rud'), - path('types/attach-tag-category/', views.EstablishmentTypeAttachTagCategoryView.as_view(), - name='type-attach-tag-category'), + # path('types/attach-tag-category/', views.EstablishmentTypeAttachTagCategoryView.as_view(), + # 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'), ] diff --git a/apps/establishment/urls/common.py b/apps/establishment/urls/common.py index 18b768c0..65b796ae 100644 --- a/apps/establishment/urls/common.py +++ b/apps/establishment/urls/common.py @@ -7,7 +7,7 @@ app_name = 'establishment' urlpatterns = [ path('', views.EstablishmentListView.as_view(), name='list'), - path('types/tags/', views.EstablishmentTypeTagListView.as_view(), name='type-tag-list'), + # path('types/tags/', views.EstablishmentTypeTagListView.as_view(), name='type-tag-list'), path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(), name='recent-reviews'), path('slug//', views.EstablishmentRetrieveView.as_view(), name='detail'), diff --git a/apps/establishment/views/back.py b/apps/establishment/views/back.py index 543dbd3e..f79707d9 100644 --- a/apps/establishment/views/back.py +++ b/apps/establishment/views/back.py @@ -55,24 +55,24 @@ class EstablishmentScheduleCreateView(generics.CreateAPIView): serializer_class = ScheduleCreateSerializer -class EstablishmentTypeAttachTagCategoryView(generics.CreateAPIView): - """Attach tag category to establishment type.""" - serializer_class = serializers.EstablishmentTypeTagCategoryBaseSerializer - - def get_queryset(self): - """Override get_queryset method.""" - return models.EstablishmentTypeTagCategory.objects.with_base_related() - - def post(self, request, *args, **kwargs): - """Overridden post-method.""" - super(EstablishmentTypeAttachTagCategoryView, self).post(request) - return Response(status=status.HTTP_200_OK) +# class EstablishmentTypeAttachTagCategoryView(generics.CreateAPIView): +# """Attach tag category to establishment type.""" +# serializer_class = serializers.EstablishmentTypeTagCategoryBaseSerializer +# +# def get_queryset(self): +# """Override get_queryset method.""" +# return models.EstablishmentTypeTagCategory.objects.with_base_related() +# +# def post(self, request, *args, **kwargs): +# """Overridden post-method.""" +# super(EstablishmentTypeAttachTagCategoryView, self).post(request) +# return Response(status=status.HTTP_200_OK) -class EstablishmentTagCreateView(EstablishmentMixinViews, generics.CreateAPIView): - """Attach tag to establishment.""" - serializer_class = serializers.EstablishmentTagCreateSerializer - +# class EstablishmentTagCreateView(EstablishmentMixinViews, generics.CreateAPIView): +# """Attach tag to establishment.""" +# serializer_class = serializers.EstablishmentTagCreateSerializer +# class MenuListCreateView(generics.ListCreateAPIView): """Menu list create view.""" @@ -164,13 +164,13 @@ class EstablishmentTypeRUDView(generics.RetrieveUpdateDestroyAPIView): queryset = models.EstablishmentType.objects.all() -class EstablishmentTypeTagListView(generics.ListAPIView): - """List of tags with categories by establishment type.""" - serializer_class = serializers.EstablishmentTagsByType - queryset = models.EstablishmentType.objects.with_base_related() - filter_class = EstablishmentTypeTagFilter - permission_classes = (permissions.AllowAny, ) - pagination_class = None +# class EstablishmentTypeTagListView(generics.ListAPIView): +# """List of tags with categories by establishment type.""" +# serializer_class = serializers.EstablishmentTagsByType +# queryset = models.EstablishmentType.objects.with_base_related() +# filter_class = EstablishmentTypeTagFilter +# permission_classes = (permissions.AllowAny, ) +# pagination_class = None class EstablishmentSubtypeListCreateView(generics.ListCreateAPIView): @@ -186,15 +186,15 @@ class EstablishmentSubtypeRUDView(generics.RetrieveUpdateDestroyAPIView): queryset = models.EstablishmentSubType.objects.all() -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 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) diff --git a/apps/search_indexes/documents/news.py b/apps/search_indexes/documents/news.py index 6e0974d8..62049c05 100644 --- a/apps/search_indexes/documents/news.py +++ b/apps/search_indexes/documents/news.py @@ -24,15 +24,15 @@ class NewsDocument(Document): country = fields.ObjectField(properties={'id': fields.IntegerField(), 'code': fields.KeywordField()}) web_url = fields.KeywordField(attr='web_url') - tags = fields.ObjectField( - properties={ - 'id': fields.IntegerField(attr='metadata.id'), - 'label': fields.ObjectField(attr='metadata.label_indexing', - properties=OBJECT_FIELD_PROPERTIES), - 'category': fields.ObjectField(attr='metadata.category', - properties={'id': fields.IntegerField()}) - }, - multi=True) + # tags = fields.ObjectField( + # properties={ + # 'id': fields.IntegerField(attr='metadata.id'), + # 'label': fields.ObjectField(attr='metadata.label_indexing', + # properties=OBJECT_FIELD_PROPERTIES), + # 'category': fields.ObjectField(attr='metadata.category', + # properties={'id': fields.IntegerField()}) + # }, + # multi=True) class Django: diff --git a/apps/tag/filters.py b/apps/tag/filters.py new file mode 100644 index 00000000..95f56b53 --- /dev/null +++ b/apps/tag/filters.py @@ -0,0 +1,48 @@ +"""Tag app filters.""" +from django_filters import rest_framework as filters +from tag import models + + +class TagCategoryFilterSet(filters.FilterSet): + """TagCategory filterset.""" + + # Object type choices + NEWS = 'news' + ESTABLISHMENT = 'establishment' + + TYPE_CHOICES = ( + (NEWS, 'News'), + (ESTABLISHMENT, 'Establishment'), + ) + + type = filters.MultipleChoiceFilter(choices=TYPE_CHOICES, + method='filter_by_type') + + # Establishment type choices + RESTAURANT = 'restaurant' + + ESTABLISHMENT_TYPE_CHOICES = ( + (RESTAURANT, 'restaurant'), + ) + + establishment_type = filters.MultipleChoiceFilter( + choices=ESTABLISHMENT_TYPE_CHOICES, + method='filter_by_establishment_type') + + class Meta: + """Meta class.""" + + model = models.TagCategory + fields = ('type', + 'establishment_type', ) + + def filter_by_type(self, queryset, name, value): + if self.NEWS in value: + queryset = queryset.for_news() + if self.ESTABLISHMENT in value: + queryset = queryset.for_establishments() + return queryset + + # todo: filter by establishment type + def filter_by_establishment_type(self, queryset, name, value): + return queryset.for_establishments() diff --git a/apps/tag/models.py b/apps/tag/models.py index b552bbcb..381e552d 100644 --- a/apps/tag/models.py +++ b/apps/tag/models.py @@ -32,8 +32,16 @@ class Tag(TranslatedFieldsMixin, models.Model): class TagCategoryQuerySet(models.QuerySet): """Extended queryset for TagCategory model.""" - def by_news_type(self, news_type): - return self.filter(news_types=news_type) + def with_base_related(self): + return self.prefetch_related('tags') + + def for_news(self): + return self.filter(news_types__isnull=True) + + def for_establishments(self): + return self.filter(models.Q(est_subtype_tag_categories__isnull=True) | + models.Q(est_type_tag_categories__isnull=True)).\ + distinct() def with_related(self): return self.select_related('country').prefetch_related('tags') diff --git a/apps/tag/serializers.py b/apps/tag/serializers.py index ecb1b68d..895fe2a1 100644 --- a/apps/tag/serializers.py +++ b/apps/tag/serializers.py @@ -13,23 +13,29 @@ class TagBaseSerializer(serializers.ModelSerializer): """Meta class.""" model = models.Tag - fields = [ + fields = ( 'id', - 'label', 'label_translated', + ) + + +class TagBackOfficeSerializer(TagBaseSerializer): + """Serializer for Tag model for Back office users.""" + + class Meta(TagBaseSerializer.Meta): + """Meta class.""" + + fields = TagBaseSerializer.Meta.fields + ( + 'label', 'category' - ] - extra_kwargs = { - 'label': {'write_only': True}, - 'category': {'write_only': True} - } + ) class TagCategoryBaseSerializer(serializers.ModelSerializer): """Serializer for model TagCategory.""" label_translated = TranslatedField() - country_translated = TranslatedField(source='country.name_translated') + tags = TagBaseSerializer(many=True, read_only=True) class Meta: """Meta class.""" @@ -37,23 +43,29 @@ class TagCategoryBaseSerializer(serializers.ModelSerializer): model = models.TagCategory fields = ( 'id', - 'label', 'label_translated', - 'country', - 'country_translated', - 'public', + 'tags' ) - extra_kwargs = { - 'label': {'write_only': True}, - 'country': {'write_only': True}, - } class TagCategoryDetailSerializer(TagCategoryBaseSerializer): - tags = TagBaseSerializer(many=True) class Meta(TagCategoryBaseSerializer.Meta): """Meta class.""" fields = TagCategoryBaseSerializer.Meta.fields + ('tags', ) + + +class TagCategoryBackOfficeDetailSerializer(TagCategoryDetailSerializer): + + country_translated = TranslatedField(source='country.name_translated') + + class Meta(TagCategoryDetailSerializer.Meta): + """Meta class.""" + + fields = TagCategoryDetailSerializer.Meta.fields + ( + 'news_types', + 'country', + 'country_translated', + ) diff --git a/apps/tag/urls/__init__.py b/apps/tag/urls/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/tag/urls.py b/apps/tag/urls/back.py similarity index 53% rename from apps/tag/urls.py rename to apps/tag/urls/back.py index 0d0b86d2..9f03bb45 100644 --- a/apps/tag/urls.py +++ b/apps/tag/urls/back.py @@ -1,10 +1,16 @@ """Urlconf for app tag.""" from django.urls import path -from . import views +from rest_framework.routers import SimpleRouter +from tag import views app_name = 'tag' +router = SimpleRouter() +router.register(r'', views.TagViewSet) + + urlpatterns = [ - path('', views.TagListCreateView.as_view(), name='list-create'), path('category/', views.TagCategoryListCreateView.as_view(), name='category-list-create'), ] + +urlpatterns += router.urls diff --git a/apps/tag/urls/web.py b/apps/tag/urls/web.py new file mode 100644 index 00000000..c99253eb --- /dev/null +++ b/apps/tag/urls/web.py @@ -0,0 +1,16 @@ +"""Tag app urlpatterns web users.""" +from rest_framework.routers import SimpleRouter +from tag import views + + +app_name = 'tag' + +router = SimpleRouter() +router.register(r'categories', views.TagCategoryViewSet) + +urlpatterns = [ + +] + +urlpatterns += router.urls + diff --git a/apps/tag/views.py b/apps/tag/views.py index 5bf4d045..2bc9d8d2 100644 --- a/apps/tag/views.py +++ b/apps/tag/views.py @@ -1,19 +1,33 @@ """Tag views.""" -from rest_framework import generics -from tag import serializers, models +from rest_framework import generics, viewsets, mixins +from tag import filters, models, serializers +from rest_framework import permissions -class TagListCreateView(generics.ListCreateAPIView): +class TagViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, + mixins.UpdateModelMixin, mixins.DestroyModelMixin, + viewsets.GenericViewSet): """List/create tag view.""" - queryset = models.Tag.objects.all() - serializer_class = serializers.TagBaseSerializer pagination_class = None + queryset = models.Tag.objects.all() + serializer_class = serializers.TagBackOfficeSerializer class TagCategoryListCreateView(generics.ListCreateAPIView): """List/create tag category view.""" - queryset = models.TagCategory.objects.all() - serializer_class = serializers.TagCategoryBaseSerializer pagination_class = None + permission_classes = (permissions.AllowAny, ) + queryset = models.TagCategory.objects.all() + serializer_class = serializers.TagCategoryBackOfficeDetailSerializer + + +class TagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): + """ViewSet for TagCategory model.""" + + filterset_class = filters.TagCategoryFilterSet + pagination_class = None + permission_classes = (permissions.AllowAny, ) + queryset = models.TagCategory.objects.with_base_related() + serializer_class = serializers.TagCategoryBaseSerializer diff --git a/project/settings/base.py b/project/settings/base.py index 4618887d..1de0c109 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -222,8 +222,8 @@ REST_FRAMEWORK = { 'COERCE_DECIMAL_TO_STRING': False, 'DEFAULT_AUTHENTICATION_CLASSES': ( # JWT - 'utils.authentication.GMJWTAuthentication', 'rest_framework.authentication.SessionAuthentication', + # 'utils.authentication.GMJWTAuthentication', ), 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning', 'DEFAULT_VERSION': (AVAILABLE_VERSIONS['current'],), diff --git a/project/urls/back.py b/project/urls/back.py index eb049b9c..389c6f51 100644 --- a/project/urls/back.py +++ b/project/urls/back.py @@ -7,7 +7,7 @@ urlpatterns = [ path('establishments/', include('establishment.urls.back')), path('location/', include('location.urls.back')), path('news/', include('news.urls.back')), - path('tags/', include(('tag.urls', 'tag'), namespace='tag')), + path('tags/', include(('tag.urls.back', 'tag'), namespace='tag')), path('account/', include('account.urls.back')), path('comment/', include('comment.urls.back')), ] diff --git a/project/urls/web.py b/project/urls/web.py index 89debab2..5bd67207 100644 --- a/project/urls/web.py +++ b/project/urls/web.py @@ -30,6 +30,7 @@ urlpatterns = [ path('location/', include('location.urls.web')), path('main/', include('main.urls')), path('recipes/', include('recipe.urls.web')), + path('tags/', include('tag.urls.web')), path('translation/', include('translation.urls')), path('comments/', include('comment.urls.web')), path('favorites/', include('favorites.urls')),