diff --git a/apps/establishment/admin.py b/apps/establishment/admin.py index 2d8fa42f..d40950b1 100644 --- a/apps/establishment/admin.py +++ b/apps/establishment/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from establishment import models from django.contrib.contenttypes.admin import GenericTabularInline -from main.models import Award +from main.models import Award, MetaDataContent @admin.register(models.EstablishmentType) @@ -20,10 +20,15 @@ class AwardInline(GenericTabularInline): extra = 0 +class MetaDataContentInline(GenericTabularInline): + model = MetaDataContent + extra = 0 + + @admin.register(models.Establishment) class EstablishmentAdmin(admin.ModelAdmin): """Establishment admin.""" - inlines = [AwardInline, ] + inlines = [AwardInline, MetaDataContentInline] @admin.register(models.EstablishmentSchedule) diff --git a/apps/establishment/filters.py b/apps/establishment/filters.py new file mode 100644 index 00000000..dc391bf6 --- /dev/null +++ b/apps/establishment/filters.py @@ -0,0 +1,16 @@ +from django_filters import FilterSet +from django_filters import rest_framework as filters + +from establishment import models + + +class EstablishmentFilter(FilterSet): + tag_id = filters.NumberFilter(field_name='tags__metadata__id',) + award_id = filters.NumberFilter(field_name='awards__id',) + + class Meta: + model = models.Establishment + fields = ( + 'tag_id', + 'award_id' + ) diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 11bff295..56cc531c 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -87,6 +87,7 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin): default=None, verbose_name=_('Price level')) awards = generic.GenericRelation(to='main.Award') + tags = generic.GenericRelation(to='main.MetaDataContent') class Meta: """Meta class.""" diff --git a/apps/establishment/serializers.py b/apps/establishment/serializers.py index dacdbe10..49788db3 100644 --- a/apps/establishment/serializers.py +++ b/apps/establishment/serializers.py @@ -1,8 +1,9 @@ """Establishment serializers.""" from rest_framework import serializers from establishment import models -from timetable import models as timetable_models from location.serializers import AddressSerializer +from main.serializers import MetaDataContentSerializer, AwardSerializer +from timetable.models import Timetable class EstablishmentTypeSerializer(serializers.ModelSerializer): @@ -35,7 +36,7 @@ class EstablishmentScheduleSerializer(serializers.ModelSerializer): class Meta: """Meta class.""" - model = timetable_models.Timetable + model = Timetable fields = ( 'weekday', 'lunch_start', @@ -53,6 +54,8 @@ class EstablishmentSerializer(serializers.ModelSerializer): type = EstablishmentTypeSerializer(source='establishment_type') subtypes = EstablishmentSubTypeSerializer(many=True) address = AddressSerializer() + tags = MetaDataContentSerializer(many=True) + awards = AwardSerializer(many=True) schedule = EstablishmentScheduleSerializer(source='schedule.schedule', many=True, allow_null=True) @@ -73,5 +76,7 @@ class EstablishmentSerializer(serializers.ModelSerializer): 'subtypes', 'image', 'address', - 'schedule' + 'tags', + 'awards', + 'schedule', ) diff --git a/apps/establishment/urls/common.py b/apps/establishment/urls/common.py index a469a2f1..605a703f 100644 --- a/apps/establishment/urls/common.py +++ b/apps/establishment/urls/common.py @@ -8,4 +8,5 @@ app_name = 'establishment' urlpatterns = [ path('', views.EstablishmentListView.as_view(), name='list'), + path('/', views.EstablishmentRetrieveView.as_view(), name='detail'), ] \ No newline at end of file diff --git a/apps/establishment/views.py b/apps/establishment/views.py index 7146aac1..459aeeac 100644 --- a/apps/establishment/views.py +++ b/apps/establishment/views.py @@ -2,6 +2,7 @@ from rest_framework import generics, permissions from establishment import models, serializers from utils.views import JWTGenericViewMixin +from establishment import filters class EstablishmentListView(JWTGenericViewMixin, generics.ListAPIView): @@ -10,6 +11,15 @@ class EstablishmentListView(JWTGenericViewMixin, generics.ListAPIView): permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentSerializer queryset = models.Establishment.objects.all() + filter_class = filters.EstablishmentFilter + + +class EstablishmentRetrieveView(JWTGenericViewMixin, generics.RetrieveAPIView): + """Resource for getting a establishment.""" + + permission_classes = (permissions.AllowAny,) + serializer_class = serializers.EstablishmentSerializer + queryset = models.Establishment.objects.all() class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView): @@ -18,3 +28,4 @@ class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView): permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentTypeSerializer queryset = models.EstablishmentType.objects.all() + diff --git a/apps/main/admin.py b/apps/main/admin.py index 1666511d..9ff6606a 100644 --- a/apps/main/admin.py +++ b/apps/main/admin.py @@ -23,3 +23,19 @@ class AwardAdmin(admin.ModelAdmin): """Award admin conf.""" # list_display = ['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""" diff --git a/apps/main/migrations/0011_auto_20190829_0821.py b/apps/main/migrations/0011_auto_20190829_0821.py new file mode 100644 index 00000000..6501af58 --- /dev/null +++ b/apps/main/migrations/0011_auto_20190829_0821.py @@ -0,0 +1,52 @@ +# Generated by Django 2.2.4 on 2019-08-29 08:21 + +from django.db import migrations, models +import django.db.models.deletion +import utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('location', '0008_auto_20190827_1302'), + ('main', '0010_award_title'), + ] + + operations = [ + migrations.CreateModel( + name='MetaData', + 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":"some text"}', null=True, verbose_name='label')), + ], + options={ + 'verbose_name': 'metadata', + 'verbose_name_plural': 'metadata', + }, + bases=(utils.models.TraslatedFieldsMixin, models.Model), + ), + migrations.CreateModel( + name='MetaDataContent', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('object_id', models.PositiveIntegerField()), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), + ('metadata', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.MetaData')), + ], + ), + migrations.CreateModel( + name='MetaDataCategory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('public', models.BooleanField()), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), + ('country', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='location.Country')), + ], + ), + migrations.AddField( + model_name='metadata', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.MetaDataCategory', verbose_name='category'), + ), + ] diff --git a/apps/main/migrations/0012_auto_20190829_1155.py b/apps/main/migrations/0012_auto_20190829_1155.py new file mode 100644 index 00000000..049c9fed --- /dev/null +++ b/apps/main/migrations/0012_auto_20190829_1155.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.4 on 2019-08-29 11:55 + +from django.db import migrations +import utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0011_auto_20190829_0821'), + ] + + operations = [ + migrations.AlterField( + model_name='award', + name='title', + field=utils.models.TJSONField(blank=True, default=None, help_text='{"en":"some text"}', null=True, verbose_name='title'), + ), + ] diff --git a/apps/main/models.py b/apps/main/models.py index 6608feb9..cb406d98 100644 --- a/apps/main/models.py +++ b/apps/main/models.py @@ -7,8 +7,8 @@ from django.utils.translation import gettext_lazy as _ from django.contrib.contenttypes.models import ContentType from location.models import Country from main import methods -from utils.models import ProjectBaseMixin - +from utils.models import ProjectBaseMixin, TJSONField, TraslatedFieldsMixin +from configuration.models import TranslationSettings # # @@ -185,10 +185,10 @@ class SiteFeature(ProjectBaseMixin): unique_together = ('site_settings', 'feature') -class Award(models.Model): +class Award(TraslatedFieldsMixin, models.Model): """Award model.""" award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE) - title = JSONField( + title = TJSONField( _('title'), null=True, blank=True, default=None, help_text='{"en":"some text"}') vintage_year = models.CharField(_('vintage year'), max_length=255, default='') @@ -199,8 +199,9 @@ class Award(models.Model): def __str__(self): title = 'None' - if self.title and 'en' in self.title: - title = self.title['en'] + lang = TranslationSettings.get_solo().default_language + if self.title and lang in self.title: + title = self.title[lang] return f'id:{self.id}-{title}' @@ -212,3 +213,40 @@ class AwardType(models.Model): def __str__(self): return self.name + + +class MetaDataCategory(models.Model): + """MetaData category model.""" + + country = models.ForeignKey( + 'location.Country', null=True, default=None, on_delete=models.CASCADE) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + public = models.BooleanField() + + +class MetaData(TraslatedFieldsMixin, models.Model): + """MetaData model.""" + label = TJSONField( + _('label'), null=True, blank=True, + default=None, help_text='{"en":"some text"}') + category = models.ForeignKey( + MetaDataCategory, verbose_name=_('category'), on_delete=models.CASCADE) + + class Meta: + verbose_name = _('metadata') + verbose_name_plural = _('metadata') + + 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 MetaDataContent(models.Model): + """MetaDataContent model.""" + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + content_object = generic.GenericForeignKey('content_type', 'object_id') + metadata = models.ForeignKey(MetaData, on_delete=models.CASCADE) diff --git a/apps/main/serializers.py b/apps/main/serializers.py index 73ec941b..478093d0 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -1,5 +1,6 @@ """Main app serializers.""" from rest_framework import serializers + from main import models @@ -72,11 +73,26 @@ class SiteSettingsSerializer(serializers.ModelSerializer): class AwardSerializer(serializers.ModelSerializer): """Award serializer.""" + title_translated = serializers.CharField(read_only=True, allow_null=True) class Meta: model = models.Award fields = [ - # 'title', + 'id', + 'title_translated', 'award_type', 'vintage_year', + ] + + +class MetaDataContentSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source='metadata.id', read_only=True,) + label_translated = serializers.CharField( + source='metadata.label_translated', read_only=True, allow_null=True) + + class Meta: + model = models.MetaDataContent + fields = [ + 'id', + 'label_translated', ] \ No newline at end of file diff --git a/apps/news/filters.py b/apps/news/filters.py index 75e66c36..7af3452d 100644 --- a/apps/news/filters.py +++ b/apps/news/filters.py @@ -8,10 +8,21 @@ class NewsListFilterSet(django_filters.FilterSet): """FilterSet for News list""" is_highlighted = django_filters.BooleanFilter() + title = django_filters.CharFilter(method='by_title') class Meta: """Meta class""" model = models.News fields = ( + 'title', 'is_highlighted', ) + + def by_title(self, queryset, name, value): + """Crappy search by title according to locale""" + if value: + locale = self.request.locale + filters = {f'{name}__{locale}': value} + return queryset.filter(**filters) + else: + return queryset diff --git a/apps/news/models.py b/apps/news/models.py index b6493a9b..e3eff57e 100644 --- a/apps/news/models.py +++ b/apps/news/models.py @@ -1,6 +1,7 @@ """News app models.""" from django.db import models from django.utils.translation import gettext_lazy as _ + from utils.models import BaseAttributes, TJSONField, TraslatedFieldsMixin diff --git a/apps/utils/middleware.py b/apps/utils/middleware.py index 398e4437..3cc57319 100644 --- a/apps/utils/middleware.py +++ b/apps/utils/middleware.py @@ -1,5 +1,6 @@ """Custom middleware.""" from django.utils import translation + from configuration.models import TranslationSettings from translation.models import Language