From 6cba003960589e9a53524d4b8a857038adf73004 Mon Sep 17 00:00:00 2001 From: evgeniy-st Date: Wed, 21 Aug 2019 11:37:22 +0300 Subject: [PATCH 1/2] Site features --- apps/main/admin.py | 5 ++ .../migrations/0002_auto_20190821_0830.py | 49 ++++++++++++++++++ apps/main/models.py | 46 ++++++++++++++++- apps/main/serializers.py | 50 +++++++++++++++---- apps/main/urls.py | 10 +++- apps/main/views.py | 39 ++++++++++++++- 6 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 apps/main/migrations/0002_auto_20190821_0830.py diff --git a/apps/main/admin.py b/apps/main/admin.py index ee9a1a07..ab34c8dc 100644 --- a/apps/main/admin.py +++ b/apps/main/admin.py @@ -6,3 +6,8 @@ from main import models @admin.register(models.SiteSettings) class SiteSettingsAdmin(admin.ModelAdmin): """Site settings admin conf.""" + + +@admin.register(models.Feature) +class FeatureAdmin(admin.ModelAdmin): + """Feature admin conf.""" diff --git a/apps/main/migrations/0002_auto_20190821_0830.py b/apps/main/migrations/0002_auto_20190821_0830.py new file mode 100644 index 00000000..8fb41331 --- /dev/null +++ b/apps/main/migrations/0002_auto_20190821_0830.py @@ -0,0 +1,49 @@ +# Generated by Django 2.2.4 on 2019-08-21 08:30 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Feature', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')), + ('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')), + ('slug', models.CharField(max_length=255, unique=True)), + ], + options={ + 'verbose_name': 'Feature', + 'verbose_name_plural': 'Features', + }, + ), + migrations.CreateModel( + name='SiteFeature', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')), + ('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')), + ('published', models.BooleanField(default=False, verbose_name='Published')), + ('feature', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='main.Feature')), + ('site_settings', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.SiteSettings')), + ], + options={ + 'verbose_name': 'Site feature', + 'verbose_name_plural': 'Site features', + 'unique_together': {('site_settings', 'feature')}, + }, + ), + migrations.AddField( + model_name='feature', + name='site_settings', + field=models.ManyToManyField(through='main.SiteFeature', to='main.SiteSettings'), + ), + ] diff --git a/apps/main/models.py b/apps/main/models.py index acbc4f8e..7ace75ae 100644 --- a/apps/main/models.py +++ b/apps/main/models.py @@ -116,4 +116,48 @@ class SiteSettings(ProjectBaseMixin): verbose_name_plural = _('Site settings') def __str__(self): - return f'Site: "{self.country_code}"' \ No newline at end of file + return f'Site: "{self.country_code}"' + + @property + def published_features(self): + return self.feature_set.filter(sitefeature__site_settings=self, + sitefeature__published=True) + + +class Feature(ProjectBaseMixin): + """Feature model.""" + + slug = models.CharField(max_length=255, unique=True) + site_settings = models.ManyToManyField(SiteSettings, through='SiteFeature') + + class Meta: + """Meta class.""" + verbose_name = _('Feature') + verbose_name_plural = _('Features') + + def __str__(self): + return f'{self.slug}' + + +class SiteFeatureQuerySet(models.QuerySet): + """Extended queryset for SiteFeature model.""" + + def published(self, switcher=True): + return self.filter(published=switcher) + + +class SiteFeature(ProjectBaseMixin): + """SiteFeature model.""" + + site_settings = models.ForeignKey(SiteSettings, on_delete=models.CASCADE) + feature = models.ForeignKey(Feature, on_delete=models.PROTECT) + published = models.BooleanField(default=False, verbose_name=_('Published')) + + objects = SiteFeatureQuerySet.as_manager() + + class Meta: + """Meta class.""" + + verbose_name = _('Site feature') + verbose_name_plural = _('Site features') + unique_together = ('site_settings', 'feature') diff --git a/apps/main/serializers.py b/apps/main/serializers.py index 86f0bda1..7cec6747 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -3,19 +3,51 @@ from rest_framework import serializers from main import models +class FeatureSerializer(serializers.ModelSerializer): + """Feature serializer.""" + + class Meta: + """Meta class.""" + + model = models.Feature + fields = ( + 'id', + 'slug', + ) + + class SiteSettingsSerializer(serializers.ModelSerializer): """Site settings serializer.""" + published_features = FeatureSerializer(many=True, allow_null=None) + class Meta: """Meta class.""" model = models.SiteSettings - fields = ('country_code', - 'pinterest_page_url', - 'twitter_page_url', - 'facebook_page_url', - 'instagram_page_url', - 'contact_email', - 'config', - 'ad_config', - ) + fields = ( + 'country_code', + 'pinterest_page_url', + 'twitter_page_url', + 'facebook_page_url', + 'instagram_page_url', + 'contact_email', + 'config', + 'ad_config', + 'published_features', + ) + + +class SiteFeatureSerializer(serializers.ModelSerializer): + """Site feature serializer.""" + + class Meta: + """Meta class.""" + + model = models.SiteFeature + fields = ( + 'id', + 'published', + 'site_settings', + 'feature', + ) diff --git a/apps/main/urls.py b/apps/main/urls.py index 0e62a784..70732879 100644 --- a/apps/main/urls.py +++ b/apps/main/urls.py @@ -6,5 +6,13 @@ app = 'main' urlpatterns = [ path('site-settings//', views.SiteSettingsView.as_view(), - name='site-settings',) + name='site-settings', ), + path('features/', views.FeaturesLCView.as_view(), + name='features-lc'), + path('features//', views.FeaturesRUDView.as_view(), + name='features-rud'), + path('site-features/', views.SiteFeaturesLCView.as_view(), + name='site-features-lc'), + path('site-features//', views.SiteFeaturesRUDView.as_view(), + name='site-features-rud'), ] \ No newline at end of file diff --git a/apps/main/views.py b/apps/main/views.py index fd5f095d..0fe4f9f1 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -4,9 +4,46 @@ from main import models, serializers class SiteSettingsView(generics.RetrieveAPIView): - """Site settings View""" + """Site settings View.""" lookup_field = 'country_code' permission_classes = (permissions.AllowAny,) queryset = models.SiteSettings.objects.all() serializer_class = serializers.SiteSettingsSerializer + + +class FeatureViewMixin: + """Feature view mixin.""" + + queryset = models.Feature.objects.all() + serializer_class = serializers.FeatureSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class FeaturesLCView(FeatureViewMixin, generics.ListCreateAPIView): + """Site features LC View.""" + + pagination_class = None + + +class FeaturesRUDView(FeatureViewMixin, generics.RetrieveUpdateDestroyAPIView): + """Site features RUD View.""" + + +class SiteFeaturesViewMixin: + """Site feature view mixin.""" + + queryset = models.SiteFeature.objects.all() + serializer_class = serializers.SiteFeatureSerializer + permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class SiteFeaturesLCView(SiteFeaturesViewMixin, generics.ListCreateAPIView): + """Site features LC.""" + + pagination_class = None + + +class SiteFeaturesRUDView(SiteFeaturesViewMixin, + generics.RetrieveUpdateDestroyAPIView): + """Site features RUD.""" From 8c46496bf1793a143d96b1f70f78cdb099f9c211 Mon Sep 17 00:00:00 2001 From: evgeniy-st Date: Wed, 21 Aug 2019 12:05:51 +0300 Subject: [PATCH 2/2] determine user`s site --- apps/main/urls.py | 2 ++ apps/main/views.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/apps/main/urls.py b/apps/main/urls.py index 70732879..6abeeabf 100644 --- a/apps/main/urls.py +++ b/apps/main/urls.py @@ -5,6 +5,8 @@ from main import views app = 'main' urlpatterns = [ + path('determine-site/', views.DetermineSiteView.as_view(), + name='determine-site'), path('site-settings//', views.SiteSettingsView.as_view(), name='site-settings', ), path('features/', views.FeaturesLCView.as_view(), diff --git a/apps/main/views.py b/apps/main/views.py index 0fe4f9f1..aa076665 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -1,4 +1,5 @@ """Main app views.""" +from django.http.response import HttpResponseRedirect from rest_framework import generics, permissions from main import models, serializers @@ -47,3 +48,12 @@ class SiteFeaturesLCView(SiteFeaturesViewMixin, generics.ListCreateAPIView): class SiteFeaturesRUDView(SiteFeaturesViewMixin, generics.RetrieveUpdateDestroyAPIView): """Site features RUD.""" + + +class DetermineSiteView(generics.GenericAPIView): + """Determine user's site.""" + + permission_classes = (permissions.AllowAny,) + + def get(self, request, *args, **kwargs): + return HttpResponseRedirect('http://ru.gm.id-east.ru/')