Merge branch 'feature/gm-192' into feature/gm-148
# Conflicts: # apps/news/models.py # apps/news/serializers.py # apps/news/views.py
This commit is contained in:
commit
2d830b2821
|
|
@ -40,8 +40,7 @@ class PasswordResetConfirmView(JWTGenericViewMixin):
|
||||||
queryset = models.User.objects.active()
|
queryset = models.User.objects.active()
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
"""Override get_object method
|
"""Override get_object method"""
|
||||||
"""
|
|
||||||
queryset = self.filter_queryset(self.get_queryset())
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
uidb64 = self.kwargs.get('uidb64')
|
uidb64 = self.kwargs.get('uidb64')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from comment.models import Comment
|
from comment.models import Comment
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from main.models import Award, MetaDataContent
|
from main.models import Award
|
||||||
from review import models as review_models
|
from review import models as review_models
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,11 +24,6 @@ class AwardInline(GenericTabularInline):
|
||||||
extra = 0
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
class MetaDataContentInline(GenericTabularInline):
|
|
||||||
model = MetaDataContent
|
|
||||||
extra = 0
|
|
||||||
|
|
||||||
|
|
||||||
class ContactPhoneInline(admin.TabularInline):
|
class ContactPhoneInline(admin.TabularInline):
|
||||||
"""Contact phone inline admin."""
|
"""Contact phone inline admin."""
|
||||||
model = models.ContactPhone
|
model = models.ContactPhone
|
||||||
|
|
@ -56,8 +51,7 @@ class EstablishmentAdmin(admin.ModelAdmin):
|
||||||
"""Establishment admin."""
|
"""Establishment admin."""
|
||||||
list_display = ['id', '__str__', 'image_tag', ]
|
list_display = ['id', '__str__', 'image_tag', ]
|
||||||
inlines = [
|
inlines = [
|
||||||
AwardInline, MetaDataContentInline,
|
AwardInline, ContactPhoneInline, ContactEmailInline,
|
||||||
ContactPhoneInline, ContactEmailInline,
|
|
||||||
ReviewInline, CommentInline]
|
ReviewInline, CommentInline]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -85,3 +79,18 @@ class MenuAdmin(admin.ModelAdmin):
|
||||||
return obj.category_translated
|
return obj.category_translated
|
||||||
|
|
||||||
category_translated.short_description = _('category')
|
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."""
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,17 @@ class EstablishmentFilter(filters.FilterSet):
|
||||||
if value not in EMPTY_VALUES:
|
if value not in EMPTY_VALUES:
|
||||||
return queryset.search(value, locale=self.request.locale)
|
return queryset.search(value, locale=self.request.locale)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentTypeTagFilter(filters.FilterSet):
|
||||||
|
"""Establishment tag filter set."""
|
||||||
|
|
||||||
|
type_id = filters.NumberFilter(field_name='id')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
model = models.EstablishmentType
|
||||||
|
fields = (
|
||||||
|
'type_id',
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-09 07:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0031_establishment_slug'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EstablishmentTag',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'establishment tag',
|
||||||
|
'verbose_name_plural': 'establishment tags',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EstablishmentTypeTagCategory',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('establishment_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tag_categories', to='establishment.EstablishmentType', verbose_name='establishment type')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'establishment type tag categories',
|
||||||
|
'verbose_name_plural': 'establishment type tag categories',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
30
apps/establishment/migrations/0033_auto_20191009_0715.py
Normal file
30
apps/establishment/migrations/0033_auto_20191009_0715.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-09 07:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tag', '0001_initial'),
|
||||||
|
('establishment', '0032_establishmenttag_establishmenttypetagcategory'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishmenttypetagcategory',
|
||||||
|
name='tag_category',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='est_type_tag_categories', to='tag.TagCategory', verbose_name='tag category'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishmenttag',
|
||||||
|
name='establishment',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tags', to='establishment.Establishment', verbose_name='establishment'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishmenttag',
|
||||||
|
name='tag',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tags', to='tag.Tag', verbose_name='tag'),
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/establishment/migrations/0034_merge_20191009_1457.py
Normal file
14
apps/establishment/migrations/0034_merge_20191009_1457.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-09 14:57
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0033_auto_20191009_0715'),
|
||||||
|
('establishment', '0033_auto_20191003_0943_squashed_0034_auto_20191003_1036'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
|
|
@ -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',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
18
apps/establishment/migrations/0036_auto_20191011_1356.py
Normal file
18
apps/establishment/migrations/0036_auto_20191011_1356.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-11 13:56
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0035_establishmentsubtypetagcategory'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='establishment_subtypes',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='subtype_establishment', to='establishment.EstablishmentSubType', verbose_name='subtype'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -16,12 +16,29 @@ from phonenumber_field.modelfields import PhoneNumberField
|
||||||
|
|
||||||
from collection.models import Collection
|
from collection.models import Collection
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
from main.models import Award, MetaDataContent
|
from main.models import Award
|
||||||
|
from tag.models import Tag, TagCategory
|
||||||
from review.models import Review
|
from review.models import Review
|
||||||
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
||||||
TranslatedFieldsMixin, BaseAttributes)
|
TranslatedFieldsMixin, BaseAttributes)
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentTypeQuerySet(models.QuerySet):
|
||||||
|
"""QuerySet for model EstablishmentType."""
|
||||||
|
|
||||||
|
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'))))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# todo: establishment type&subtypes check
|
# todo: establishment type&subtypes check
|
||||||
class EstablishmentType(TranslatedFieldsMixin, ProjectBaseMixin):
|
class EstablishmentType(TranslatedFieldsMixin, ProjectBaseMixin):
|
||||||
"""Establishment type model."""
|
"""Establishment type model."""
|
||||||
|
|
@ -32,6 +49,8 @@ class EstablishmentType(TranslatedFieldsMixin, ProjectBaseMixin):
|
||||||
help_text='{"en-GB":"some text"}')
|
help_text='{"en-GB":"some text"}')
|
||||||
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
|
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
|
||||||
|
|
||||||
|
objects = EstablishmentTypeQuerySet.as_manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
||||||
|
|
@ -76,10 +95,13 @@ class EstablishmentQuerySet(models.QuerySet):
|
||||||
|
|
||||||
def with_base_related(self):
|
def with_base_related(self):
|
||||||
"""Return qs with related objects."""
|
"""Return qs with related objects."""
|
||||||
return self.select_related('address').prefetch_related(
|
return self.select_related('address', 'establishment_type').prefetch_related(
|
||||||
models.Prefetch('tags',
|
models.Prefetch('tags',
|
||||||
MetaDataContent.objects.select_related(
|
EstablishmentTag.objects.select_related('tag')),
|
||||||
'metadata__category'))
|
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):
|
def with_extended_related(self):
|
||||||
|
|
@ -256,6 +278,7 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
verbose_name=_('type'))
|
verbose_name=_('type'))
|
||||||
establishment_subtypes = models.ManyToManyField(EstablishmentSubType,
|
establishment_subtypes = models.ManyToManyField(EstablishmentSubType,
|
||||||
|
blank=True,
|
||||||
related_name='subtype_establishment',
|
related_name='subtype_establishment',
|
||||||
verbose_name=_('subtype'))
|
verbose_name=_('subtype'))
|
||||||
address = models.ForeignKey(Address, blank=True, null=True, default=None,
|
address = models.ForeignKey(Address, blank=True, null=True, default=None,
|
||||||
|
|
@ -478,6 +501,7 @@ class ContactEmail(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.email}'
|
return f'{self.email}'
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# class Wine(TranslatedFieldsMixin, models.Model):
|
# class Wine(TranslatedFieldsMixin, models.Model):
|
||||||
# """Wine model."""
|
# """Wine model."""
|
||||||
|
|
@ -551,3 +575,82 @@ class SocialNetwork(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
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 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')
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from establishment.serializers import (
|
from establishment.serializers import (
|
||||||
EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer,
|
EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer,
|
||||||
ContactPhonesSerializer, SocialNetworkRelatedSerializers,
|
ContactPhonesSerializer, SocialNetworkRelatedSerializers,
|
||||||
EstablishmentTypeSerializer)
|
EstablishmentTypeBaseSerializer, EstablishmentSubTypeBaseSerializer,
|
||||||
|
EstablishmentTypeTagCategoryBaseSerializer)
|
||||||
from utils.decorators import with_base_attributes
|
|
||||||
|
|
||||||
from main.models import Currency
|
from main.models import Currency
|
||||||
|
from tag.serializers import TagBaseSerializer
|
||||||
|
from utils.decorators import with_base_attributes
|
||||||
|
from utils.serializers import TranslatedField
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
||||||
|
|
@ -21,7 +24,7 @@ class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
||||||
emails = ContactEmailsSerializer(read_only=True, many=True, )
|
emails = ContactEmailsSerializer(read_only=True, many=True, )
|
||||||
socials = SocialNetworkRelatedSerializers(read_only=True, many=True, )
|
socials = SocialNetworkRelatedSerializers(read_only=True, many=True, )
|
||||||
slug = serializers.SlugField(required=True, allow_blank=False, max_length=50)
|
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:
|
class Meta:
|
||||||
model = models.Establishment
|
model = models.Establishment
|
||||||
|
|
@ -55,7 +58,7 @@ class EstablishmentRUDSerializer(EstablishmentBaseSerializer):
|
||||||
phones = ContactPhonesSerializer(read_only=False, many=True, )
|
phones = ContactPhonesSerializer(read_only=False, many=True, )
|
||||||
emails = ContactEmailsSerializer(read_only=False, many=True, )
|
emails = ContactEmailsSerializer(read_only=False, many=True, )
|
||||||
socials = SocialNetworkRelatedSerializers(read_only=False, many=True, )
|
socials = SocialNetworkRelatedSerializers(read_only=False, many=True, )
|
||||||
type = EstablishmentTypeSerializer(source='establishment_type')
|
type = EstablishmentTypeBaseSerializer(source='establishment_type')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Establishment
|
model = models.Establishment
|
||||||
|
|
@ -142,3 +145,95 @@ class EmployeeBackSerializers(serializers.ModelSerializer):
|
||||||
'name'
|
'name'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
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',
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
"""Establishment serializers."""
|
"""Establishment serializers."""
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from comment import models as comment_models
|
from comment import models as comment_models
|
||||||
from comment.serializers import common as comment_serializers
|
from comment.serializers import common as comment_serializers
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from favorites.models import Favorites
|
from favorites.models import Favorites
|
||||||
from location.serializers import AddressBaseSerializer
|
from location.serializers import AddressBaseSerializer
|
||||||
from main.models import MetaDataContent
|
from main.serializers import AwardSerializer, CurrencySerializer
|
||||||
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
|
|
||||||
from review import models as review_models
|
from review import models as review_models
|
||||||
|
from tag.serializers import TagBaseSerializer
|
||||||
from timetable.serialziers import ScheduleRUDSerializer
|
from timetable.serialziers import ScheduleRUDSerializer
|
||||||
from utils import exceptions as utils_exceptions
|
from utils import exceptions as utils_exceptions
|
||||||
from utils.serializers import TranslatedField, ProjectModelSerializer
|
from utils.serializers import ProjectModelSerializer
|
||||||
|
from utils.serializers import TranslatedField
|
||||||
|
|
||||||
|
|
||||||
class ContactPhonesSerializer(serializers.ModelSerializer):
|
class ContactPhonesSerializer(serializers.ModelSerializer):
|
||||||
|
|
@ -86,30 +88,6 @@ class MenuRUDSerializers(ProjectModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentTypeSerializer(serializers.ModelSerializer):
|
|
||||||
"""Serializer for EstablishmentType model."""
|
|
||||||
|
|
||||||
name_translated = serializers.CharField(allow_null=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
"""Meta class."""
|
|
||||||
|
|
||||||
model = models.EstablishmentType
|
|
||||||
fields = ('id', 'name_translated')
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentSubTypeSerializer(serializers.ModelSerializer):
|
|
||||||
"""Serializer for EstablishmentSubType models."""
|
|
||||||
|
|
||||||
name_translated = serializers.CharField(allow_null=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
"""Meta class."""
|
|
||||||
|
|
||||||
model = models.EstablishmentSubType
|
|
||||||
fields = ('id', 'name_translated')
|
|
||||||
|
|
||||||
|
|
||||||
class ReviewSerializer(serializers.ModelSerializer):
|
class ReviewSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for model Review."""
|
"""Serializer for model Review."""
|
||||||
text_translated = serializers.CharField(read_only=True)
|
text_translated = serializers.CharField(read_only=True)
|
||||||
|
|
@ -122,6 +100,75 @@ class ReviewSerializer(serializers.ModelSerializer):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
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):
|
class EstablishmentEmployeeSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for actual employees."""
|
"""Serializer for actual employees."""
|
||||||
|
|
||||||
|
|
@ -138,14 +185,28 @@ class EstablishmentEmployeeSerializer(serializers.ModelSerializer):
|
||||||
fields = ('id', 'name', 'position_translated', 'awards', 'priority')
|
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 EstablishmentBaseSerializer(ProjectModelSerializer):
|
class EstablishmentBaseSerializer(ProjectModelSerializer):
|
||||||
"""Base serializer for Establishment model."""
|
"""Base serializer for Establishment model."""
|
||||||
|
|
||||||
preview_image = serializers.URLField(source='preview_image_url')
|
preview_image = serializers.URLField(source='preview_image_url')
|
||||||
slug = serializers.SlugField(allow_blank=False, required=True, max_length=50)
|
slug = serializers.SlugField(allow_blank=False, required=True, max_length=50)
|
||||||
address = AddressBaseSerializer()
|
address = AddressBaseSerializer()
|
||||||
tags = MetaDataContentSerializer(many=True)
|
|
||||||
in_favorites = serializers.BooleanField(allow_null=True)
|
in_favorites = serializers.BooleanField(allow_null=True)
|
||||||
|
tags = EstablishmentTagSerializer(many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -171,8 +232,8 @@ class EstablishmentDetailSerializer(EstablishmentBaseSerializer):
|
||||||
|
|
||||||
description_translated = TranslatedField()
|
description_translated = TranslatedField()
|
||||||
image = serializers.URLField(source='image_url')
|
image = serializers.URLField(source='image_url')
|
||||||
type = EstablishmentTypeSerializer(source='establishment_type', read_only=True)
|
type = EstablishmentTypeBaseSerializer(source='establishment_type', read_only=True)
|
||||||
subtypes = EstablishmentSubTypeSerializer(many=True, source='establishment_subtypes')
|
subtypes = EstablishmentSubTypeBaseSerializer(many=True, source='establishment_subtypes')
|
||||||
awards = AwardSerializer(many=True)
|
awards = AwardSerializer(many=True)
|
||||||
schedule = ScheduleRUDSerializer(many=True, allow_null=True)
|
schedule = ScheduleRUDSerializer(many=True, allow_null=True)
|
||||||
phones = ContactPhonesSerializer(read_only=True, many=True)
|
phones = ContactPhonesSerializer(read_only=True, many=True)
|
||||||
|
|
@ -306,17 +367,3 @@ class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer):
|
||||||
})
|
})
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentTagListSerializer(serializers.ModelSerializer):
|
|
||||||
"""List establishment tag serializer."""
|
|
||||||
id = serializers.IntegerField(source='metadata.id')
|
|
||||||
label_translated = serializers.CharField(
|
|
||||||
source='metadata.label_translated', read_only=True, allow_null=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
"""Meta class."""
|
|
||||||
model = MetaDataContent
|
|
||||||
fields = [
|
|
||||||
'id',
|
|
||||||
'label_translated',
|
|
||||||
]
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ urlpatterns = [
|
||||||
name='schedule-rud'),
|
name='schedule-rud'),
|
||||||
path('<int:pk>/schedule/', views.EstablishmentScheduleCreateView.as_view(),
|
path('<int:pk>/schedule/', views.EstablishmentScheduleCreateView.as_view(),
|
||||||
name='schedule-create'),
|
name='schedule-create'),
|
||||||
|
path('attach-tag/', views.EstablishmentTagCreateView.as_view(), name='attach-tag'),
|
||||||
path('menus/', views.MenuListCreateView.as_view(), name='menu-list'),
|
path('menus/', views.MenuListCreateView.as_view(), name='menu-list'),
|
||||||
path('menus/<int:pk>/', views.MenuRUDView.as_view(), name='menu-rud'),
|
path('menus/<int:pk>/', views.MenuRUDView.as_view(), name='menu-rud'),
|
||||||
path('plates/', views.PlateListCreateView.as_view(), name='plates'),
|
path('plates/', views.PlateListCreateView.as_view(), name='plates'),
|
||||||
|
|
@ -26,4 +27,13 @@ urlpatterns = [
|
||||||
path('emails/<int:pk>/', views.EmailRUDView.as_view(), name='emails-rud'),
|
path('emails/<int:pk>/', views.EmailRUDView.as_view(), name='emails-rud'),
|
||||||
path('employees/', views.EmployeeListCreateView.as_view(), name='employees'),
|
path('employees/', views.EmployeeListCreateView.as_view(), name='employees'),
|
||||||
path('employees/<int:pk>/', views.EmployeeRUDView.as_view(), name='employees-rud'),
|
path('employees/<int:pk>/', 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/<int:pk>/', views.EstablishmentTypeRUDView.as_view(), name='type-rud'),
|
||||||
|
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/<int:pk>/', views.EstablishmentSubtypeRUDView.as_view(), name='subtype-rud'),
|
||||||
|
path('subtypes/attach-tag-category/', views.EstablishmentSubTypeAttachTagCategoryView.as_view(),
|
||||||
|
name='subtype-attach-tag-category'),
|
||||||
]
|
]
|
||||||
|
|
@ -7,7 +7,6 @@ app_name = 'establishment'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.EstablishmentListView.as_view(), name='list'),
|
path('', views.EstablishmentListView.as_view(), name='list'),
|
||||||
path('tags/', views.EstablishmentTagListView.as_view(), name='tags'),
|
|
||||||
path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(),
|
path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(),
|
||||||
name='recent-reviews'),
|
name='recent-reviews'),
|
||||||
path('slug/<slug:slug>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
path('slug/<slug:slug>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
"""Establishment app views."""
|
"""Establishment app views."""
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from rest_framework import generics, status, permissions
|
||||||
|
|
||||||
from rest_framework import generics
|
from establishment import models, serializers
|
||||||
|
from rest_framework.response import Response
|
||||||
from establishment import models
|
from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer
|
||||||
from establishment import serializers
|
from establishment.filters import EstablishmentTypeTagFilter
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentMixinViews:
|
class EstablishmentMixinViews:
|
||||||
|
|
@ -25,6 +27,53 @@ class EstablishmentRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
serializer_class = serializers.EstablishmentRUDSerializer
|
serializer_class = serializers.EstablishmentRUDSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
"""Establishment schedule RUD view"""
|
||||||
|
serializer_class = ScheduleRUDSerializer
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""
|
||||||
|
Returns the object the view is displaying.
|
||||||
|
"""
|
||||||
|
establishment_pk = self.kwargs['pk']
|
||||||
|
schedule_id = self.kwargs['schedule_id']
|
||||||
|
|
||||||
|
establishment = get_object_or_404(klass=models.Establishment.objects.all(),
|
||||||
|
pk=establishment_pk)
|
||||||
|
schedule = get_object_or_404(klass=establishment.schedule,
|
||||||
|
id=schedule_id)
|
||||||
|
|
||||||
|
# May raise a permission denied
|
||||||
|
self.check_object_permissions(self.request, establishment)
|
||||||
|
self.check_object_permissions(self.request, schedule)
|
||||||
|
|
||||||
|
return schedule
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentScheduleCreateView(generics.CreateAPIView):
|
||||||
|
"""Establishment schedule Create view"""
|
||||||
|
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 EstablishmentTagCreateView(EstablishmentMixinViews, generics.CreateAPIView):
|
||||||
|
"""Attach tag to establishment."""
|
||||||
|
serializer_class = serializers.EstablishmentTagCreateSerializer
|
||||||
|
|
||||||
|
|
||||||
class MenuListCreateView(generics.ListCreateAPIView):
|
class MenuListCreateView(generics.ListCreateAPIView):
|
||||||
"""Menu list create view."""
|
"""Menu list create view."""
|
||||||
serializer_class = serializers.MenuSerializers
|
serializer_class = serializers.MenuSerializers
|
||||||
|
|
@ -100,3 +149,52 @@ class EmployeeRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""Social RUD view."""
|
"""Social RUD view."""
|
||||||
serializer_class = serializers.EmployeeBackSerializers
|
serializer_class = serializers.EmployeeBackSerializers
|
||||||
queryset = models.Employee.objects.all()
|
queryset = models.Employee.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentTypeListCreateView(generics.ListCreateAPIView):
|
||||||
|
"""Establishment type list/create view."""
|
||||||
|
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.EstablishmentTypeBaseSerializer
|
||||||
|
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 EstablishmentSubtypeListCreateView(generics.ListCreateAPIView):
|
||||||
|
"""Establishment subtype list/create view."""
|
||||||
|
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.EstablishmentSubTypeBaseSerializer
|
||||||
|
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)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ from establishment import filters
|
||||||
from establishment import models, serializers
|
from establishment import models, serializers
|
||||||
from main import methods
|
from main import methods
|
||||||
from main.models import MetaDataContent
|
from main.models import MetaDataContent
|
||||||
from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer
|
|
||||||
from utils.pagination import EstablishmentPortionPagination
|
from utils.pagination import EstablishmentPortionPagination
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -19,9 +18,10 @@ class EstablishmentMixinView:
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Overrided method 'get_queryset'."""
|
"""Overridden method 'get_queryset'."""
|
||||||
return models.Establishment.objects.published().with_base_related().\
|
return models.Establishment.objects.published() \
|
||||||
annotate_in_favorites(self.request.user)
|
.with_base_related() \
|
||||||
|
.annotate_in_favorites(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListView(EstablishmentMixinView, generics.ListAPIView):
|
class EstablishmentListView(EstablishmentMixinView, generics.ListAPIView):
|
||||||
|
|
@ -84,7 +84,7 @@ class EstablishmentTypeListView(generics.ListAPIView):
|
||||||
"""Resource for getting a list of establishment types."""
|
"""Resource for getting a list of establishment types."""
|
||||||
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
serializer_class = serializers.EstablishmentTypeSerializer
|
serializer_class = serializers.EstablishmentTypeBaseSerializer
|
||||||
queryset = models.EstablishmentType.objects.all()
|
queryset = models.EstablishmentType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -174,44 +174,3 @@ class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIVi
|
||||||
return qs.by_distance_from_point(**{k: v for k, v in filter_kwargs.items()
|
return qs.by_distance_from_point(**{k: v for k, v in filter_kwargs.items()
|
||||||
if v is not None})
|
if v is not None})
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentTagListView(generics.ListAPIView):
|
|
||||||
"""List view for establishment tags."""
|
|
||||||
serializer_class = serializers.EstablishmentTagListSerializer
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
|
||||||
pagination_class = None
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
"""Override get_queryset method"""
|
|
||||||
return MetaDataContent.objects.by_content_type(app_label='establishment',
|
|
||||||
model='establishment')\
|
|
||||||
.distinct('metadata__label')
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
|
|
||||||
"""Establishment schedule RUD view"""
|
|
||||||
serializer_class = ScheduleRUDSerializer
|
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
"""
|
|
||||||
Returns the object the view is displaying.
|
|
||||||
"""
|
|
||||||
establishment_pk = self.kwargs['pk']
|
|
||||||
schedule_id = self.kwargs['schedule_id']
|
|
||||||
|
|
||||||
establishment = get_object_or_404(klass=models.Establishment.objects.all(),
|
|
||||||
pk=establishment_pk)
|
|
||||||
schedule = get_object_or_404(klass=establishment.schedule,
|
|
||||||
id=schedule_id)
|
|
||||||
|
|
||||||
# May raise a permission denied
|
|
||||||
self.check_object_permissions(self.request, establishment)
|
|
||||||
self.check_object_permissions(self.request, schedule)
|
|
||||||
|
|
||||||
return schedule
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentScheduleCreateView(generics.CreateAPIView):
|
|
||||||
"""Establishment schedule Create view"""
|
|
||||||
serializer_class = ScheduleCreateSerializer
|
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,6 @@ class AwardAdmin(admin.ModelAdmin):
|
||||||
# list_display_links = ['id', '__str__']
|
# list_display_links = ['id', '__str__']
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.MetaData)
|
|
||||||
class MetaDataAdmin(admin.ModelAdmin):
|
|
||||||
"""MetaData admin."""
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.MetaDataCategory)
|
|
||||||
class MetaDataCategoryAdmin(admin.ModelAdmin):
|
|
||||||
"""MetaData admin."""
|
|
||||||
list_display = ['id', 'country', 'content_type']
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.MetaDataContent)
|
|
||||||
class MetaDataContentAdmin(admin.ModelAdmin):
|
|
||||||
"""MetaDataContent admin"""
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Currency)
|
@admin.register(models.Currency)
|
||||||
class CurrencContentAdmin(admin.ModelAdmin):
|
class CurrencContentAdmin(admin.ModelAdmin):
|
||||||
"""CurrencContent admin"""
|
"""CurrencContent admin"""
|
||||||
|
|
|
||||||
24
apps/news/migrations/0021_auto_20191009_1408.py
Normal file
24
apps/news/migrations/0021_auto_20191009_1408.py
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-09 14:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tag', '0002_auto_20191009_1408'),
|
||||||
|
('news', '0020_remove_news_author'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='news',
|
||||||
|
name='tags',
|
||||||
|
field=models.ManyToManyField(related_name='news', to='tag.Tag', verbose_name='Tags'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='newstype',
|
||||||
|
name='tag_categories',
|
||||||
|
field=models.ManyToManyField(related_name='news_types', to='tag.TagCategory'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -12,6 +12,8 @@ class NewsType(models.Model):
|
||||||
"""NewsType model."""
|
"""NewsType model."""
|
||||||
|
|
||||||
name = models.CharField(_('name'), max_length=250)
|
name = models.CharField(_('name'), max_length=250)
|
||||||
|
tag_categories = models.ManyToManyField('tag.TagCategory',
|
||||||
|
related_name='news_types')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -133,8 +135,8 @@ class News(BaseAttributes, TranslatedFieldsMixin):
|
||||||
country = models.ForeignKey('location.Country', blank=True, null=True,
|
country = models.ForeignKey('location.Country', blank=True, null=True,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
verbose_name=_('country'))
|
verbose_name=_('country'))
|
||||||
tags = generic.GenericRelation(to='main.MetaDataContent')
|
tags = models.ManyToManyField('tag.Tag', related_name='news',
|
||||||
|
verbose_name=_('Tags'))
|
||||||
gallery = models.ManyToManyField('gallery.Image', through='news.NewsGallery')
|
gallery = models.ManyToManyField('gallery.Image', through='news.NewsGallery')
|
||||||
ratings = generic.GenericRelation(Rating)
|
ratings = generic.GenericRelation(Rating)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ from account.serializers.common import UserBaseSerializer
|
||||||
from gallery.models import Image
|
from gallery.models import Image
|
||||||
from location import models as location_models
|
from location import models as location_models
|
||||||
from location.serializers import CountrySimpleSerializer
|
from location.serializers import CountrySimpleSerializer
|
||||||
from main.serializers import MetaDataContentSerializer
|
|
||||||
from news import models
|
from news import models
|
||||||
|
from tag.serializers import TagBaseSerializer
|
||||||
from utils.serializers import TranslatedField, ProjectModelSerializer
|
from utils.serializers import TranslatedField, ProjectModelSerializer
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ class NewsBaseSerializer(ProjectModelSerializer):
|
||||||
|
|
||||||
# related fields
|
# related fields
|
||||||
news_type = NewsTypeSerializer(read_only=True)
|
news_type = NewsTypeSerializer(read_only=True)
|
||||||
tags = MetaDataContentSerializer(read_only=True, many=True)
|
tags = TagBaseSerializer(read_only=True, many=True)
|
||||||
gallery = NewsImageSerializer(read_only=True, many=True)
|
gallery = NewsImageSerializer(read_only=True, many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,7 @@ app_name = 'news'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.NewsListView.as_view(), name='list'),
|
path('', views.NewsListView.as_view(), name='list'),
|
||||||
path('types/', views.NewsTypeListView.as_view(), name='type'),
|
path('types/', views.NewsTypeListView.as_view(), name='type'),
|
||||||
|
path('types/<int:pk>/tags/', views.NewsTypeTagsView.as_view(),
|
||||||
|
name='type-tags'),
|
||||||
path('slug/<slug:slug>/', views.NewsDetailView.as_view(), name='rud'),
|
path('slug/<slug:slug>/', views.NewsDetailView.as_view(), name='rud'),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
"""News app views."""
|
"""News app views."""
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from rest_framework import generics, permissions
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.transaction import on_commit
|
from django.db.transaction import on_commit
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
@ -8,6 +10,8 @@ from rest_framework.response import Response
|
||||||
from gallery.tasks import delete_image
|
from gallery.tasks import delete_image
|
||||||
from news import filters, models, serializers
|
from news import filters, models, serializers
|
||||||
from rating.tasks import add_rating
|
from rating.tasks import add_rating
|
||||||
|
from tag.serializers import TagCategoryDetailSerializer
|
||||||
|
|
||||||
|
|
||||||
class NewsMixinView:
|
class NewsMixinView:
|
||||||
"""News mixin."""
|
"""News mixin."""
|
||||||
|
|
@ -40,6 +44,7 @@ class NewsDetailView(NewsMixinView, generics.RetrieveAPIView):
|
||||||
"""Override get_queryset method."""
|
"""Override get_queryset method."""
|
||||||
return super().get_queryset().with_extended_related()
|
return super().get_queryset().with_extended_related()
|
||||||
|
|
||||||
|
|
||||||
class NewsTypeListView(generics.ListAPIView):
|
class NewsTypeListView(generics.ListAPIView):
|
||||||
"""NewsType list view."""
|
"""NewsType list view."""
|
||||||
|
|
||||||
|
|
@ -49,6 +54,18 @@ class NewsTypeListView(generics.ListAPIView):
|
||||||
serializer_class = serializers.NewsTypeSerializer
|
serializer_class = serializers.NewsTypeSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class NewsTypeTagsView(generics.ListAPIView):
|
||||||
|
"""Resource to get a list of tags for a news type."""
|
||||||
|
|
||||||
|
pagination_class = None
|
||||||
|
permission_classes = (permissions.AllowAny, )
|
||||||
|
serializer_class = TagCategoryDetailSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
news_type = get_object_or_404(models.NewsType, pk=self.kwargs.get('pk'))
|
||||||
|
return news_type.tag_categories.with_related()
|
||||||
|
|
||||||
|
|
||||||
class NewsBackOfficeMixinView:
|
class NewsBackOfficeMixinView:
|
||||||
"""News back office mixin view."""
|
"""News back office mixin view."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,24 +21,29 @@ class EstablishmentDocument(Document):
|
||||||
properties={
|
properties={
|
||||||
'id': fields.IntegerField(),
|
'id': fields.IntegerField(),
|
||||||
'name': fields.ObjectField(attr='name_indexing',
|
'name': fields.ObjectField(attr='name_indexing',
|
||||||
properties=OBJECT_FIELD_PROPERTIES)
|
properties=OBJECT_FIELD_PROPERTIES),
|
||||||
|
'tag_categories': fields.ObjectField(properties={
|
||||||
|
'tag_category': fields.ObjectField(
|
||||||
|
properties={
|
||||||
|
'id': fields.IntegerField()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
establishment_subtypes = fields.ObjectField(
|
establishment_subtypes = fields.ObjectField(
|
||||||
properties={
|
properties={
|
||||||
'id': fields.IntegerField(),
|
'id': fields.IntegerField(),
|
||||||
'name': fields.ObjectField(attr='name_indexing',
|
'name': fields.ObjectField(attr='name_indexing',
|
||||||
properties=OBJECT_FIELD_PROPERTIES)
|
properties={
|
||||||
|
'id': fields.IntegerField(),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
multi=True)
|
multi=True)
|
||||||
tags = fields.ObjectField(
|
tags = fields.ObjectField(
|
||||||
properties={
|
properties={
|
||||||
'id': fields.IntegerField(attr='metadata.id'),
|
'tag': fields.ObjectField(properties={
|
||||||
'label': fields.ObjectField(attr='metadata.label_indexing',
|
'id': fields.IntegerField(),
|
||||||
properties=OBJECT_FIELD_PROPERTIES),
|
}),
|
||||||
'category': fields.ObjectField(attr='metadata.category',
|
|
||||||
properties={
|
|
||||||
'id': fields.IntegerField(),
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
multi=True)
|
multi=True)
|
||||||
address = fields.ObjectField(
|
address = fields.ObjectField(
|
||||||
|
|
|
||||||
0
apps/tag/__init__.py
Normal file
0
apps/tag/__init__.py
Normal file
12
apps/tag/admin.py
Normal file
12
apps/tag/admin.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from .models import Tag, TagCategory
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Tag)
|
||||||
|
class TagAdmin(admin.ModelAdmin):
|
||||||
|
"""Admin model for model Tag."""
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(TagCategory)
|
||||||
|
class TagCategoryAdmin(admin.ModelAdmin):
|
||||||
|
"""Admin model for model TagCategory."""
|
||||||
7
apps/tag/apps.py
Normal file
7
apps/tag/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class TagConfig(AppConfig):
|
||||||
|
name = 'tag'
|
||||||
|
verbose_name = _('tag')
|
||||||
44
apps/tag/migrations/0001_initial.py
Normal file
44
apps/tag/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-09 07:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('location', '0010_auto_20190904_0711'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TagCategory',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('label', utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='label')),
|
||||||
|
('public', models.BooleanField(default=False)),
|
||||||
|
('country', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='location.Country')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'tag category',
|
||||||
|
'verbose_name_plural': 'tag categories',
|
||||||
|
},
|
||||||
|
bases=(utils.models.TranslatedFieldsMixin, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Tag',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('label', utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='label')),
|
||||||
|
('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tags', to='tag.TagCategory', verbose_name='category')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'tag',
|
||||||
|
'verbose_name_plural': 'tags',
|
||||||
|
},
|
||||||
|
bases=(utils.models.TranslatedFieldsMixin, models.Model),
|
||||||
|
),
|
||||||
|
]
|
||||||
27
apps/tag/migrations/0002_auto_20191009_1408.py
Normal file
27
apps/tag/migrations/0002_auto_20191009_1408.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-10-09 14:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tag', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='tag',
|
||||||
|
options={'verbose_name': 'Tag', 'verbose_name_plural': 'Tags'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='tagcategory',
|
||||||
|
options={'verbose_name': 'Tag category', 'verbose_name_plural': 'Tag categories'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='tag',
|
||||||
|
name='category',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tags', to='tag.TagCategory', verbose_name='Category'),
|
||||||
|
),
|
||||||
|
]
|
||||||
0
apps/tag/migrations/__init__.py
Normal file
0
apps/tag/migrations/__init__.py
Normal file
66
apps/tag/models.py
Normal file
66
apps/tag/models.py
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
"""Tag app models."""
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from configuration.models import TranslationSettings
|
||||||
|
from utils.models import TJSONField, TranslatedFieldsMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Tag(TranslatedFieldsMixin, models.Model):
|
||||||
|
"""Tag model."""
|
||||||
|
|
||||||
|
label = TJSONField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('label'),
|
||||||
|
help_text='{"en-GB":"some text"}')
|
||||||
|
category = models.ForeignKey('TagCategory', on_delete=models.PROTECT,
|
||||||
|
null=True, related_name='tags',
|
||||||
|
verbose_name=_('Category'))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
verbose_name = _('Tag')
|
||||||
|
verbose_name_plural = _('Tags')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
label = 'None'
|
||||||
|
lang = TranslationSettings.get_solo().default_language
|
||||||
|
if self.label and lang in self.label:
|
||||||
|
label = self.label[lang]
|
||||||
|
return f'id:{self.id}-{label}'
|
||||||
|
|
||||||
|
|
||||||
|
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_related(self):
|
||||||
|
return self.select_related('country').prefetch_related('tags')
|
||||||
|
|
||||||
|
|
||||||
|
class TagCategory(TranslatedFieldsMixin, models.Model):
|
||||||
|
"""Tag base category model."""
|
||||||
|
|
||||||
|
label = TJSONField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('label'),
|
||||||
|
help_text='{"en-GB":"some text"}')
|
||||||
|
country = models.ForeignKey('location.Country',
|
||||||
|
on_delete=models.SET_NULL, null=True,
|
||||||
|
default=None)
|
||||||
|
public = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
objects = TagCategoryQuerySet.as_manager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
verbose_name = _('Tag category')
|
||||||
|
verbose_name_plural = _('Tag categories')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
label = 'None'
|
||||||
|
lang = TranslationSettings.get_solo().default_language
|
||||||
|
if self.label and lang in self.label:
|
||||||
|
label = self.label[lang]
|
||||||
|
return f'id:{self.id}-{label}'
|
||||||
59
apps/tag/serializers.py
Normal file
59
apps/tag/serializers.py
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
"""Tag serializers."""
|
||||||
|
from rest_framework import serializers
|
||||||
|
from tag import models
|
||||||
|
from utils.serializers import TranslatedField
|
||||||
|
|
||||||
|
|
||||||
|
class TagBaseSerializer(serializers.ModelSerializer):
|
||||||
|
"""Serializer for model Tag."""
|
||||||
|
|
||||||
|
label_translated = TranslatedField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
model = models.Tag
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'label',
|
||||||
|
'label_translated',
|
||||||
|
'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')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
model = models.TagCategory
|
||||||
|
fields = (
|
||||||
|
'id',
|
||||||
|
'label',
|
||||||
|
'label_translated',
|
||||||
|
'country',
|
||||||
|
'country_translated',
|
||||||
|
'public',
|
||||||
|
)
|
||||||
|
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', )
|
||||||
3
apps/tag/tests.py
Normal file
3
apps/tag/tests.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
10
apps/tag/urls.py
Normal file
10
apps/tag/urls.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
"""Urlconf for app tag."""
|
||||||
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
app_name = 'tag'
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.TagListCreateView.as_view(), name='list-create'),
|
||||||
|
path('category/', views.TagCategoryListCreateView.as_view(), name='category-list-create'),
|
||||||
|
]
|
||||||
19
apps/tag/views.py
Normal file
19
apps/tag/views.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
"""Tag views."""
|
||||||
|
from rest_framework import generics
|
||||||
|
from tag import serializers, models
|
||||||
|
|
||||||
|
|
||||||
|
class TagListCreateView(generics.ListCreateAPIView):
|
||||||
|
"""List/create tag view."""
|
||||||
|
|
||||||
|
queryset = models.Tag.objects.all()
|
||||||
|
serializer_class = serializers.TagBaseSerializer
|
||||||
|
pagination_class = None
|
||||||
|
|
||||||
|
|
||||||
|
class TagCategoryListCreateView(generics.ListCreateAPIView):
|
||||||
|
"""List/create tag category view."""
|
||||||
|
|
||||||
|
queryset = models.TagCategory.objects.all()
|
||||||
|
serializer_class = serializers.TagCategoryBaseSerializer
|
||||||
|
pagination_class = None
|
||||||
|
|
@ -73,6 +73,7 @@ PROJECT_APPS = [
|
||||||
'comment.apps.CommentConfig',
|
'comment.apps.CommentConfig',
|
||||||
'favorites.apps.FavoritesConfig',
|
'favorites.apps.FavoritesConfig',
|
||||||
'rating.apps.RatingConfig',
|
'rating.apps.RatingConfig',
|
||||||
|
'tag.apps.TagConfig',
|
||||||
]
|
]
|
||||||
|
|
||||||
EXTERNAL_APPS = [
|
EXTERNAL_APPS = [
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ from django.urls import path, include
|
||||||
app_name = 'back'
|
app_name = 'back'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('gallery/', include(('gallery.urls', 'gallery'),
|
path('gallery/', include(('gallery.urls', 'gallery'), namespace='gallery')),
|
||||||
namespace='gallery')),
|
|
||||||
path('establishments/', include('establishment.urls.back')),
|
path('establishments/', include('establishment.urls.back')),
|
||||||
path('location/', include('location.urls.back')),
|
path('location/', include('location.urls.back')),
|
||||||
path('news/', include('news.urls.back')),
|
path('news/', include('news.urls.back')),
|
||||||
|
path('tags/', include(('tag.urls', 'tag'), namespace='tag'))
|
||||||
path('account/', include('account.urls.back')),
|
path('account/', include('account.urls.back')),
|
||||||
path('comment/', include('comment.urls.back')),
|
path('comment/', include('comment.urls.back')),
|
||||||
]
|
]
|
||||||
|
|
@ -24,7 +24,8 @@ urlpatterns = [
|
||||||
path('collections/', include('collection.urls.web')),
|
path('collections/', include('collection.urls.web')),
|
||||||
path('establishments/', include('establishment.urls.web')),
|
path('establishments/', include('establishment.urls.web')),
|
||||||
path('news/', include('news.urls.web')),
|
path('news/', include('news.urls.web')),
|
||||||
path('notifications/', include(('notification.urls.web', "notification"), namespace='notification')),
|
path('notifications/', include(('notification.urls.web', "notification"),
|
||||||
|
namespace='notification')),
|
||||||
path('partner/', include('partner.urls.web')),
|
path('partner/', include('partner.urls.web')),
|
||||||
path('location/', include('location.urls.web')),
|
path('location/', include('location.urls.web')),
|
||||||
path('main/', include('main.urls')),
|
path('main/', include('main.urls')),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user