Merge branch 'develop' into feature/permission_winery

This commit is contained in:
Виктор Гладких 2019-12-09 09:40:33 +03:00
commit bd567200c8
13 changed files with 127 additions and 15 deletions

View File

@ -1,3 +1,3 @@
FROM mdillon/postgis:latest FROM mdillon/postgis:10
RUN localedef -i ru_RU -c -f UTF-8 -A /usr/share/locale/locale.alias ru_RU.UTF-8 RUN localedef -i ru_RU -c -f UTF-8 -A /usr/share/locale/locale.alias ru_RU.UTF-8
ENV LANG ru_RU.utf8 ENV LANG ru_RU.utf8

View File

@ -16,7 +16,24 @@ class RoleSerializer(serializers.ModelSerializer):
class BackUserSerializer(serializers.ModelSerializer): class BackUserSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = User model = User
fields = '__all__' fields = (
'id',
'last_login',
'is_superuser',
'username',
'last_name',
'first_name',
'is_active',
'date_joined',
'image_url',
'cropped_image_url',
'email',
'email_confirmed',
'unconfirmed_email',
'email_confirmed',
'newsletter',
'roles',
)
extra_kwargs = { extra_kwargs = {
'password': {'write_only': True} 'password': {'write_only': True}
} }

View File

@ -1,5 +1,6 @@
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions from rest_framework import generics, permissions
from rest_framework.filters import OrderingFilter
from account import models from account import models
from account.models import User from account.models import User
@ -18,10 +19,10 @@ class UserRoleLstView(generics.ListCreateAPIView):
class UserLstView(generics.ListCreateAPIView): class UserLstView(generics.ListCreateAPIView):
"""User list create view.""" """User list create view."""
queryset = User.objects.all() queryset = User.objects.prefetch_related('roles')
serializer_class = serializers.BackUserSerializer serializer_class = serializers.BackUserSerializer
permission_classes = (permissions.IsAdminUser,) permission_classes = (permissions.IsAdminUser,)
filter_backends = (DjangoFilterBackend,) filter_backends = (DjangoFilterBackend, OrderingFilter)
filterset_fields = ( filterset_fields = (
'email_confirmed', 'email_confirmed',
'is_staff', 'is_staff',
@ -29,6 +30,14 @@ class UserLstView(generics.ListCreateAPIView):
'is_superuser', 'is_superuser',
'roles', 'roles',
) )
ordering_fields = (
'email_confirmed',
'is_staff',
'is_active',
'is_superuser',
'roles',
'last_login'
)
class UserRUDView(generics.RetrieveUpdateDestroyAPIView): class UserRUDView(generics.RetrieveUpdateDestroyAPIView):

View File

@ -87,6 +87,42 @@ class Collection(ProjectBaseMixin, CollectionDateMixin,
verbose_name = _('collection') verbose_name = _('collection')
verbose_name_plural = _('collections') verbose_name_plural = _('collections')
@property
def _related_objects(self) -> list:
"""Return list of related objects."""
related_objects = []
# get related objects
for related_object in self._meta.related_objects:
related_objects.append(related_object)
return related_objects
@property
def count_related_objects(self) -> int:
"""Return count of related objects."""
counter = 0
# count of related objects
for related_object in [related_object.name for related_object in self._related_objects]:
counter += getattr(self, f'{related_object}').count()
return counter
@property
def related_object_names(self) -> list:
"""Return related object names."""
raw_object_names = []
for related_object in [related_object.name for related_object in self._related_objects]:
instances = getattr(self, f'{related_object}')
if instances.exists():
for instance in instances.all():
raw_object_names.append(instance.slug if hasattr(instance, 'slug') else None)
# parse slugs
object_names = []
re_pattern = r'[\w]+'
for raw_name in raw_object_names:
result = re.findall(re_pattern, raw_name)
if result: object_names.append(' '.join(result).capitalize())
return set(object_names)
class GuideTypeQuerySet(models.QuerySet): class GuideTypeQuerySet(models.QuerySet):
"""QuerySet for model GuideType.""" """QuerySet for model GuideType."""

View File

@ -19,6 +19,8 @@ class CollectionBackOfficeSerializer(CollectionBaseSerializer):
collection_type_display = serializers.CharField( collection_type_display = serializers.CharField(
source='get_collection_type_display', read_only=True) source='get_collection_type_display', read_only=True)
country = CountrySimpleSerializer(read_only=True) country = CountrySimpleSerializer(read_only=True)
count_related_objects = serializers.IntegerField(read_only=True)
related_object_names = serializers.ListField(read_only=True)
class Meta: class Meta:
model = models.Collection model = models.Collection
@ -36,6 +38,8 @@ class CollectionBackOfficeSerializer(CollectionBaseSerializer):
'slug', 'slug',
'start', 'start',
'end', 'end',
'count_related_objects',
'related_object_names',
] ]

View File

@ -114,10 +114,7 @@ class EstablishmentCommentListView(generics.ListAPIView):
"""Override get_queryset method""" """Override get_queryset method"""
establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug']) establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug'])
return comment_models.Comment.objects.by_content_type(app_label='establishment', return establishment.comments.order_by('-created')
model='establishment') \
.by_object_id(object_id=establishment.pk) \
.order_by('-created')
class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView): class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView):

View File

@ -0,0 +1,37 @@
from django.core.management.base import BaseCommand
from tqdm import tqdm
from establishment.models import Establishment
from main.models import Carousel
from transfer.models import HomePages
from location.models import Country
from django.db.models import F
class Command(BaseCommand):
help = '''Add establishment form HomePage to Carousel!'''
@staticmethod
def get_country(country_code):
return Country.objects.filter(code__iexact=country_code).first()
def handle(self, *args, **kwargs):
objects = []
deleted = 0
hp_list = HomePages.objects.annotate(
country=F('site__country_code_2'),
).all()
for hm in tqdm(hp_list, desc='Add home_page.establishments to carousel'):
est = Establishment.objects.filter(old_id=hm.selection_of_week).first()
if est:
if est.carousels.exists():
est.carousels.all().delete()
deleted += 1
carousel = Carousel(
content_object=est,
country=self.get_country(hm.country)
)
objects.append(carousel)
Carousel.objects.bulk_create(objects)
self.stdout.write(
self.style.WARNING(f'Created {len(objects)}/Deleted {deleted} carousel objects.'))

View File

@ -60,10 +60,7 @@ class ProductCommentListView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
"""Override get_queryset method""" """Override get_queryset method"""
product = get_object_or_404(Product, slug=self.kwargs['slug']) product = get_object_or_404(Product, slug=self.kwargs['slug'])
return Comment.objects.by_content_type(app_label='product', return product.comments.order_by('-created')
model='product') \
.by_object_id(object_id=product.pk) \
.order_by('-created')
class ProductCommentRUDView(generics.RetrieveUpdateDestroyAPIView): class ProductCommentRUDView(generics.RetrieveUpdateDestroyAPIView):

View File

@ -1000,7 +1000,7 @@ class ProductNotes(MigrateMixin):
db_table = 'product_notes' db_table = 'product_notes'
class HomePages(models.Model): class HomePages(MigrateMixin):
using = 'legacy' using = 'legacy'
site = models.ForeignKey(Sites, models.DO_NOTHING, blank=True, null=True) site = models.ForeignKey(Sites, models.DO_NOTHING, blank=True, null=True)

View File

@ -1,5 +1,6 @@
"""Custom middleware.""" """Custom middleware."""
from django.utils import translation from django.utils import translation, timezone
from account.models import User
from configuration.models import TranslationSettings from configuration.models import TranslationSettings
from translation.models import Language from translation.models import Language
@ -12,6 +13,14 @@ def get_locale(cookie_dict):
def get_country_code(cookie_dict): def get_country_code(cookie_dict):
return cookie_dict.get('country_code') return cookie_dict.get('country_code')
def user_last_visit(get_response):
"""Updates user last visit w/ current"""
def middleware(request):
response = get_response(request)
if request.user.is_authenticated:
User.objects.filter(pk=request.user.pk).update(last_login=timezone.now())
return response
return middleware
def parse_cookies(get_response): def parse_cookies(get_response):
"""Parse cookies.""" """Parse cookies."""

View File

@ -2,6 +2,8 @@
./manage.py transfer -a ./manage.py transfer -a
./manage.py transfer -d ./manage.py transfer -d
./manage.py transfer -e ./manage.py transfer -e
./manage.py transfer -n
./manage.py rm_empty_images # команда для удаления картинок с относительным урлом из news.description
./manage.py upd_transportation ./manage.py upd_transportation
./manage.py transfer --fill_city_gallery ./manage.py transfer --fill_city_gallery
./manage.py transfer -l ./manage.py transfer -l

View File

@ -118,6 +118,7 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'utils.middleware.parse_cookies', 'utils.middleware.parse_cookies',
'utils.middleware.user_last_visit',
] ]
ROOT_URLCONF = 'project.urls' ROOT_URLCONF = 'project.urls'
@ -524,3 +525,6 @@ INTERNATIONAL_COUNTRY_CODES = ['www', 'main', 'next']
THUMBNAIL_ENGINE = 'utils.thumbnail_engine.GMEngine' THUMBNAIL_ENGINE = 'utils.thumbnail_engine.GMEngine'
COOKIE_DOMAIN = None COOKIE_DOMAIN = None
ELASTICSEARCH_DSL = {}
ELASTICSEARCH_INDEX_NAMES = {}

View File

@ -42,7 +42,7 @@ DATABASES = {
'HOST': os.environ.get('DB_HOSTNAME'), 'HOST': os.environ.get('DB_HOSTNAME'),
'PORT': os.environ.get('DB_PORT'), 'PORT': os.environ.get('DB_PORT'),
'OPTIONS': { 'OPTIONS': {
'options': '-c search_path=gm' 'options': '-c search_path=gm,public'
}, },
}, },
'legacy': { 'legacy': {