intermediate commit

This commit is contained in:
Anatoly 2020-01-30 10:28:01 +03:00
parent 236b532d98
commit 57e63111fb
22 changed files with 497 additions and 369 deletions

View File

@ -1,8 +1,10 @@
"""Account models"""
from collections import Counter
from datetime import datetime
from django.contrib.postgres.search import TrigramSimilarity
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager as BaseUserManager
from django.contrib.postgres.search import TrigramSimilarity
from django.core.mail import send_mail
from django.db import models
from django.template.loader import render_to_string, get_template
@ -11,8 +13,8 @@ from django.utils.encoding import force_bytes
from django.utils.html import mark_safe
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import ugettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from rest_framework.authtoken.models import Token
from collections import Counter
from authorization.models import Application
from establishment.models import Establishment, EstablishmentSubType
@ -21,7 +23,6 @@ from main.models import SiteSettings
from utils.models import GMTokenGenerator
from utils.models import ImageMixin, ProjectBaseMixin, PlatformMixin
from utils.tokens import GMRefreshToken
from phonenumber_field.modelfields import PhoneNumberField
class RoleQuerySet(models.QuerySet):
@ -449,6 +450,31 @@ class User(AbstractUser):
result.append(item.id)
return set(result)
@property
def is_country_admin(self):
if self.userrole_set:
return self.userrole_set.country_admin().exists()
@property
def is_establishment_manager(self):
if self.userrole_set:
return self.userrole_set.establishment_manager().exists()
@property
def is_establishment_administrator(self):
if self.userrole_set:
return self.userrole_set.establishment_administrator().exists()
@property
def administrated_country_codes(self) -> list:
if self.userrole_set:
return list(
self.userrole_set
.exclude(role__site__isnull=True)
.values_list('role__site__country__code', flat=True)
.distinct()
)
class UserRoleQueryset(models.QuerySet):
"""QuerySet for model UserRole."""
@ -498,17 +524,26 @@ class UserRoleQueryset(models.QuerySet):
"""Filter QuerySet by state."""
return self.filter(state=self.model.VALIDATED)
def has_access_to_establishments(self):
"""Return QuerySet filtered by role and state."""
return self.filter(role__role__in=Role.ESTABLISHMENT_EDITORS).validated()
def country_admin(self):
"""Return status by role and state"""
return (
self.filter(role__role=Role.COUNTRY_ADMIN)
.validated()
)
def has_access_to_products(self):
"""Return QuerySet filtered by role and state."""
return self.filter(role__role__in=Role.PRODUCT_EDITORS).validated()
def establishment_manager(self):
"""Return status by role and state"""
return (
self.filter(role__role=Role.ESTABLISHMENT_MANAGER)
.validated()
)
def has_access_to_content_pages(self):
"""Return QuerySet filtered by role and state."""
return self.filter(role__role__in=Role.CONTENT_PAGE_MANAGER).validated()
def establishment_administrator(self):
"""Return status by role and state"""
return (
self.filter(role__role=Role.ESTABLISHMENT_ADMINISTRATOR)
.validated()
)
class UserRole(ProjectBaseMixin):

View File

@ -1,32 +1,29 @@
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions, status
from rest_framework.response import Response
from rest_framework.filters import OrderingFilter
import csv
from django.http import HttpResponse, HttpResponseNotFound
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, status
from rest_framework.authtoken.models import Token
from rest_framework.filters import OrderingFilter
from rest_framework.response import Response
from account import models, filters
from account.models import User
from account.serializers import back as serializers
from account.serializers.common import RoleBaseSerializer
from utils.permissions import *
from utils.methods import get_permission_classes
from utils.permissions import IsReviewManager
class RoleListView(generics.ListCreateAPIView):
serializer_class = RoleBaseSerializer
queryset = models.Role.objects.all()
filter_class = filters.RoleListFilter
permission_classes = [
IsCountryAdmin
]
permission_classes = get_permission_classes()
class RoleTypeRetrieveView(generics.GenericAPIView):
permission_classes = [
permissions.IsAdminUser |
IsCountryAdmin
]
permission_classes = get_permission_classes()
def get(self, request, *args, **kwargs):
"""Implement GET-method"""
@ -43,21 +40,15 @@ class RoleTypeRetrieveView(generics.GenericAPIView):
class UserRoleListView(generics.ListCreateAPIView):
serializer_class = serializers.UserRoleSerializer
queryset = models.UserRole.objects.all()
permission_classes = [
IsCountryAdmin
]
permission_classes = get_permission_classes()
class UserListView(generics.ListCreateAPIView):
"""User list create view."""
serializer_class = serializers.BackUserSerializer
permission_classes = [
permissions.IsAdminUser |
IsReviewManager |
IsCountryAdmin
]
filter_class = filters.AccountBackOfficeFilter
filter_backends = (OrderingFilter, DjangoFilterBackend)
permission_classes = get_permission_classes(IsReviewManager)
ordering_fields = (
'email_confirmed',
@ -77,8 +68,8 @@ class UserRUDView(generics.RetrieveUpdateDestroyAPIView):
"""User RUD view."""
queryset = User.objects.all()
serializer_class = serializers.BackDetailUserSerializer
permission_classes = (permissions.IsAdminUser,)
lookup_field = 'id'
permission_classes = get_permission_classes()
def get_user_csv(request, id):

View File

@ -1,20 +1,21 @@
"""Back office views for app advertisement"""
from django.shortcuts import get_object_or_404
from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework import permissions
from django.shortcuts import get_object_or_404
from main.serializers import PageExtendedSerializer
from advertisement.models import Advertisement
from advertisement.serializers import (AdvertisementBaseSerializer,
AdvertisementDetailSerializer)
from advertisement.serializers import (
AdvertisementBaseSerializer,
AdvertisementDetailSerializer)
from main.serializers import PageExtendedSerializer
from utils.methods import get_permission_classes
class AdvertisementBackOfficeViewMixin(generics.GenericAPIView):
"""Base back office advertisement view."""
pagination_class = None
permission_classes = (permissions.IsAuthenticated, )
permission_classes = get_permission_classes()
def get_queryset(self):
"""Overridden get queryset method."""

View File

@ -9,6 +9,7 @@ from rest_framework.response import Response
from collection import models, serializers
from collection import tasks
from utils.methods import get_permission_classes
from utils.views import BindObjectMixin
@ -16,8 +17,8 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
"""ViewSet for Collection model."""
# pagination_class = None
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.CollectionBackOfficeSerializer
permission_classes = get_permission_classes()
def get_queryset(self):
"""Overridden method 'get_queryset'."""
@ -30,7 +31,7 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
class GuideBaseView(generics.GenericAPIView):
"""ViewSet for Guide model."""
serializer_class = serializers.GuideBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes()
def get_queryset(self):
"""Overridden get_queryset method."""
@ -47,7 +48,7 @@ class GuideFilterBaseView(generics.GenericAPIView):
pagination_class = None
queryset = models.GuideFilter.objects.all()
serializer_class = serializers.GuideFilterBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes()
class GuideElementBaseView(generics.GenericAPIView):
@ -55,7 +56,7 @@ class GuideElementBaseView(generics.GenericAPIView):
pagination_class = None
queryset = models.GuideElement.objects.all()
serializer_class = serializers.GuideElementBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes()
class AdvertorialBaseView(generics.GenericAPIView):
@ -63,7 +64,7 @@ class AdvertorialBaseView(generics.GenericAPIView):
pagination_class = None
queryset = models.Advertorial.objects.all()
serializer_class = serializers.AdvertorialBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes()
class CollectionBackOfficeViewSet(mixins.CreateModelMixin,
@ -74,11 +75,11 @@ class CollectionBackOfficeViewSet(mixins.CreateModelMixin,
CollectionViewSet):
"""ViewSet for Collection model for BackOffice users."""
permission_classes = (permissions.IsAuthenticated,)
queryset = models.Collection.objects.all()
filter_backends = [DjangoFilterBackend, OrderingFilter]
serializer_class = serializers.CollectionBackOfficeSerializer
bind_object_serializer_class = serializers.CollectionBindObjectSerializer
permission_classes = get_permission_classes()
ordering_fields = ('rank', 'start')
ordering = ('-start', )
@ -183,7 +184,7 @@ class GuideElementExportXMLView(generics.ListAPIView):
pagination_class = None
queryset = models.GuideElement.objects.all()
serializer_class = serializers.GuideElementBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes()
def get(self, request, *args, **kwargs):
"""Overridden get_queryset method."""
@ -199,7 +200,7 @@ class GuideElementExportDOCView(generics.ListAPIView):
pagination_class = None
queryset = models.GuideElement.objects.all()
serializer_class = serializers.GuideElementBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes()
def get(self, request, *args, **kwargs):
"""Overridden get_queryset method."""

View File

@ -2,22 +2,20 @@ from rest_framework import generics
from comment import models
from comment.serializers import CommentBaseSerializer
from utils.permissions import IsModerator, IsCountryAdmin
from utils.methods import get_permission_classes
from utils.permissions import IsModerator
class CommentLstView(generics.ListCreateAPIView):
"""Comment list create view."""
serializer_class = CommentBaseSerializer
queryset = models.Comment.objects.all()
permission_classes = [
IsModerator |
IsCountryAdmin
]
permission_classes = get_permission_classes(IsModerator)
class CommentRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Comment RUD view."""
serializer_class = CommentBaseSerializer
queryset = models.Comment.objects.all()
permission_classes = [IsModerator]
permission_classes = get_permission_classes(IsModerator)
lookup_field = 'id'

View File

@ -2,33 +2,33 @@
from datetime import datetime
from functools import reduce
from operator import or_
from typing import List
from typing import List, Union
import elasticsearch_dsl
from django.conf import settings
from django.shortcuts import get_object_or_404
from django.contrib.contenttypes import fields as generic
from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance as DistanceMeasure
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.search import TrigramDistance, TrigramSimilarity
from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import TrigramSimilarity
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator, FileExtensionValidator
from django.db import models
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch, Sum
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from timezone_field import TimeZoneField
from location.models import Address
from timetable.models import Timetable
from location.models import WineOriginAddressMixin
from main.models import Award, Currency
from review.models import Review
from tag.models import Tag
from timetable.models import Timetable
from utils.methods import transform_into_readable_str
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
TranslatedFieldsMixin, BaseAttributes, GalleryMixin,
@ -184,9 +184,10 @@ class EstablishmentQuerySet(models.QuerySet):
"""Return establishments by country code"""
return self.filter(address__city__country=country)
def by_country_code(self, code):
def by_country_code(self, codes: Union[iter, str]):
"""Return establishments by country code"""
return self.filter(address__city__country__code=code)
codes = codes if hasattr(codes, '__iter__') else [codes]
return self.filter(address__city__country__code__in=codes)
def published(self):
"""
@ -518,31 +519,27 @@ class EstablishmentQuerySet(models.QuerySet):
to_attr='main_image')
)
def user_role_establishments(self, user, country_code: str = None):
"""Return QuerySet with establishment that is available for editing."""
def available_establishments(self, user):
"""Return QuerySet with establishment that user has an access."""
from account.models import UserRole
available_ids = Subquery(
UserRole.objects.filter(user=user)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
)
administrator_establishment_ids = []
filters = {}
if country_code:
filters.update({'address__city__country__code': country_code,
'id__in': available_ids})
return self.filter(**filters)
# put in array administrated establishment ids
if user.is_establishment_administrator:
administrator_establishment_ids.extend(
UserRole.objects.filter(user=user)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
)
# check if user is_staff
if not user.is_staff:
filters.update({'address__city__country__code__in': user.administrated_country_codes})
def available_objects(self, user, country_code: str = None):
# role without establishment
# role that has establishment
access_roles = user.userrole_set.has_access_to_establishments()
if access_roles.exists():
return self.user_role_establishments(user, country_code)
return self.none()
return self.filter(**filters).union(
self.filter(id__in=administrator_establishment_ids)
)
class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin,

View File

@ -1,7 +1,7 @@
"""Establishment app views."""
from django.shortcuts import get_object_or_404
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions, status
from rest_framework import generics, status
from rest_framework.response import Response
from account.models import User
@ -9,10 +9,9 @@ from establishment import filters, models, serializers
from establishment.models import EstablishmentEmployee
from timetable.models import Timetable
from timetable.serialziers import ScheduleCreateSerializer, ScheduleRUDSerializer
from utils.methods import get_permission_classes
from utils.permissions import (
IsCountryAdmin, IsEstablishmentManager,
IsWineryWineInspector, IsEstablishmentAdministrator,
IsReviewManager, IsRestaurantInspector
IsEstablishmentManager, IsEstablishmentAdministrator, IsReviewManager,
)
from utils.views import CreateDestroyGalleryViewMixin
@ -22,40 +21,32 @@ class EstablishmentMixinViews:
def get_queryset(self):
"""Overridden method 'get_queryset'."""
return models.Establishment.objects.with_base_related()
queryset = models.Establishment.objects.with_base_related
if hasattr(self, 'request') and \
(hasattr(self.request, 'user') and hasattr(self.request, 'country_code')):
return queryset().available_establishments(self.request.user)
return queryset().none()
class EstablishmentListCreateView(EstablishmentMixinViews, generics.ListCreateAPIView):
"""Establishment list/create view."""
filter_class = filters.EstablishmentFilter
permission_classes = [
IsReviewManager |
IsWineryWineInspector |
IsCountryAdmin |
IsEstablishmentManager |
IsEstablishmentAdministrator
]
queryset = models.Establishment.objects.all()
serializer_class = serializers.EstablishmentListCreateSerializer
def get_queryset(self):
"""Overridden get_queryset method."""
qs = super(EstablishmentListCreateView, self).get_queryset()
return qs.available_objects(self.request.user, self.request.country_code)
permission_classes = get_permission_classes(
IsReviewManager,
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class EmployeeEstablishmentsListView(generics.ListAPIView):
"""Establishment by employee list view."""
permission_classes = [
IsWineryWineInspector |
IsCountryAdmin |
IsEstablishmentManager
]
queryset = models.Establishment.objects.all()
serializer_class = serializers.EstablishmentListCreateSerializer
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
def get_queryset(self):
pk = self.kwargs.get('pk')
@ -63,30 +54,31 @@ class EmployeeEstablishmentsListView(generics.ListAPIView):
return employee.establishments.with_extended_related()
class EstablishmentRUDView(generics.RetrieveUpdateDestroyAPIView):
class EstablishmentRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView):
lookup_field = 'slug'
queryset = models.Establishment.objects.all().prefetch_related(
'establishmentemployee_set',
'establishmentemployee_set__establishment',
)
serializer_class = serializers.EstablishmentRUDSerializer
permission_classes = [
# IsWineryWineInspector |
# IsCountryAdmin |
# IsEstablishmentManager |
IsEstablishmentAdministrator
# IsRestaurantInspector
]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
def get_queryset(self):
"""Overridden get_queryset method."""
qs = super(EstablishmentRUDView, self).get_queryset()
return qs.prefetch_related(
'establishmentemployee_set',
'establishmentemployee_set__establishment',
)
class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
class EstablishmentScheduleRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView):
"""Establishment schedule RUD view"""
lookup_field = 'slug'
serializer_class = ScheduleRUDSerializer
permission_classes = [
IsWineryWineInspector |
IsEstablishmentManager
]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
def get_object(self):
"""
@ -95,7 +87,7 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
establishment_slug = self.kwargs['slug']
schedule_id = self.kwargs['schedule_id']
establishment = get_object_or_404(klass=models.Establishment.objects.all(),
establishment = get_object_or_404(klass=super(EstablishmentScheduleRUDView, self).get_queryset(),
slug=establishment_slug)
schedule = get_object_or_404(klass=establishment.schedule,
id=schedule_id)
@ -112,21 +104,21 @@ class EstablishmentScheduleCreateView(generics.CreateAPIView):
lookup_field = 'slug'
serializer_class = ScheduleCreateSerializer
queryset = Timetable.objects.all()
permission_classes = [
IsWineryWineInspector |
IsEstablishmentManager
]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class MenuListCreateView(generics.ListCreateAPIView):
"""Menu list create view."""
serializer_class = serializers.MenuSerializers
queryset = models.Menu.objects.all()
permission_classes = [
IsWineryWineInspector |
IsEstablishmentManager
]
filter_backends = (DjangoFilterBackend,)
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
filterset_fields = (
'establishment',
'establishment__slug',
@ -137,10 +129,10 @@ class MenuRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Menu RUD view."""
serializer_class = serializers.MenuRUDSerializers
queryset = models.Menu.objects.all()
permission_classes = [
IsWineryWineInspector |
IsEstablishmentManager
]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class SocialChoiceListCreateView(generics.ListCreateAPIView):
@ -148,14 +140,20 @@ class SocialChoiceListCreateView(generics.ListCreateAPIView):
serializer_class = serializers.SocialChoiceSerializers
queryset = models.SocialChoice.objects.all()
pagination_class = None
permission_classes = [permissions.IsAdminUser]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class SocialChoiceRUDView(generics.RetrieveUpdateDestroyAPIView):
"""SocialChoice RUD view."""
serializer_class = serializers.SocialChoiceSerializers
queryset = models.SocialChoice.objects.all()
permission_classes = [permissions.IsAdminUser]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class SocialListCreateView(generics.ListCreateAPIView):
@ -163,14 +161,20 @@ class SocialListCreateView(generics.ListCreateAPIView):
serializer_class = serializers.SocialNetworkSerializers
queryset = models.SocialNetwork.objects.all()
pagination_class = None
permission_classes = [permissions.IsAdminUser]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class SocialRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Social RUD view."""
serializer_class = serializers.SocialNetworkSerializers
queryset = models.SocialNetwork.objects.all()
permission_classes = [IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class PlateListCreateView(generics.ListCreateAPIView):
@ -178,14 +182,20 @@ class PlateListCreateView(generics.ListCreateAPIView):
serializer_class = serializers.PlatesSerializers
queryset = models.Plate.objects.all()
pagination_class = None
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
class PlateRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Plate RUD view."""
serializer_class = serializers.PlatesSerializers
queryset = models.Plate.objects.all()
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
class PhonesListCreateView(generics.ListCreateAPIView):
@ -193,14 +203,20 @@ class PhonesListCreateView(generics.ListCreateAPIView):
serializer_class = serializers.ContactPhoneBackSerializers
queryset = models.ContactPhone.objects.all()
pagination_class = None
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
class PhonesRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Phones RUD view."""
serializer_class = serializers.ContactPhoneBackSerializers
queryset = models.ContactPhone.objects.all()
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
class EmailListCreateView(generics.ListCreateAPIView):
@ -208,38 +224,53 @@ class EmailListCreateView(generics.ListCreateAPIView):
serializer_class = serializers.ContactEmailBackSerializers
queryset = models.ContactEmail.objects.all()
pagination_class = None
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
class EmailRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Email RUD view."""
serializer_class = serializers.ContactEmailBackSerializers
queryset = models.ContactEmail.objects.all()
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
class EmployeeListCreateView(generics.ListCreateAPIView):
"""Employee list create view."""
permission_classes = (permissions.AllowAny,)
filter_class = filters.EmployeeBackFilter
serializer_class = serializers.EmployeeBackSerializers
queryset = models.Employee.objects.all().distinct().with_back_office_related()
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class EmployeesListSearchViews(generics.ListAPIView):
"""Employee search view"""
pagination_class = None
permission_classes = (permissions.AllowAny,)
queryset = models.Employee.objects.all().with_back_office_related().select_related('photo')
filter_class = filters.EmployeeBackSearchFilter
serializer_class = serializers.EmployeeBackSerializers
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class EstablishmentEmployeeListView(generics.ListCreateAPIView):
"""Establishment emplyoees list view."""
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.EstEmployeeBackSerializer
pagination_class = None
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
def get_queryset(self):
establishment_id = self.kwargs['establishment_id']
@ -251,13 +282,18 @@ class EstablishmentEmployeeListView(generics.ListCreateAPIView):
class EmployeeRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Employee RUD view."""
serializer_class = serializers.EmployeeBackSerializers
queryset = models.Employee.objects.all().with_back_office_related()
queryset = models.Employee.objects.with_back_office_related()
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
class RemoveAwardView(generics.DestroyAPIView):
lookup_field = 'pk'
serializer_class = serializers.EmployeeBackSerializers
queryset = models.Employee.objects.all().with_back_office_related()
queryset = models.Employee.objects.with_back_office_related()
permission_classes = get_permission_classes()
def get_object(self):
employee = super().get_object()
@ -272,27 +308,31 @@ class RemoveAwardView(generics.DestroyAPIView):
class EstablishmentTypeListCreateView(generics.ListCreateAPIView):
"""Establishment type list/create view."""
serializer_class = serializers.EstablishmentTypeBaseSerializer
queryset = models.EstablishmentType.objects.all().select_related('default_image')
queryset = models.EstablishmentType.objects.select_related('default_image')
pagination_class = None
permission_classes = get_permission_classes()
class EstablishmentTypeRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Establishment type retrieve/update/destroy view."""
serializer_class = serializers.EstablishmentTypeBaseSerializer
queryset = models.EstablishmentType.objects.all().select_related('default_image')
queryset = models.EstablishmentType.objects.select_related('default_image')
permission_classes = get_permission_classes()
class EstablishmentSubtypeListCreateView(generics.ListCreateAPIView):
"""Establishment subtype list/create view."""
serializer_class = serializers.EstablishmentSubTypeBaseSerializer
queryset = models.EstablishmentSubType.objects.all().select_related('default_image')
queryset = models.EstablishmentSubType.objects.select_related('default_image')
pagination_class = None
permission_classes = get_permission_classes()
class EstablishmentSubtypeRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Establishment subtype retrieve/update/destroy view."""
serializer_class = serializers.EstablishmentSubTypeBaseSerializer
queryset = models.EstablishmentSubType.objects.all().select_related('default_image')
queryset = models.EstablishmentSubType.objects.select_related('default_image')
permission_classes = get_permission_classes()
class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews,
@ -300,6 +340,7 @@ class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews,
"""Resource for a create|destroy gallery for establishment for back-office users."""
lookup_field = 'slug'
serializer_class = serializers.EstablishmentBackOfficeGallerySerializer
permission_classes = get_permission_classes()
def get_object(self):
"""
@ -322,6 +363,7 @@ class EstablishmentGalleryListView(EstablishmentMixinViews,
"""Resource for returning gallery for establishment for back-office users."""
lookup_field = 'slug'
serializer_class = serializers.ImageBaseSerializer
permission_classes = get_permission_classes()
def get_object(self):
"""Override get_object method."""
@ -344,13 +386,14 @@ class EstablishmentCompanyListCreateView(EstablishmentMixinViews,
lookup_field = 'slug'
serializer_class = serializers.EstablishmentCompanyListCreateSerializer
permission_classes = get_permission_classes()
def get_object(self):
"""Returns the object the view is displaying."""
establishment_qs = models.Establishment.objects.all()
filtered_ad_qs = self.filter_queryset(establishment_qs)
establishment_qs = super(EstablishmentCompanyListCreateView, self).get_queryset()
filtered_qs = self.filter_queryset(establishment_qs)
establishment = get_object_or_404(filtered_ad_qs, slug=self.kwargs.get('slug'))
establishment = get_object_or_404(filtered_qs, slug=self.kwargs.get('slug'))
# May raise a permission denied
self.check_object_permissions(self.request, establishment)
@ -368,10 +411,11 @@ class EstablishmentCompanyRUDView(EstablishmentMixinViews,
lookup_field = 'slug'
serializer_class = serializers.CompanyBaseSerializer
permission_classes = get_permission_classes()
def get_object(self):
"""Returns the object the view is displaying."""
establishment_qs = models.Establishment.objects.all()
establishment_qs = super(EstablishmentCompanyRUDView, self).get_queryset()
filtered_ad_qs = self.filter_queryset(establishment_qs)
establishment = get_object_or_404(filtered_ad_qs, slug=self.kwargs.get('slug'))
@ -389,10 +433,14 @@ class EstablishmentNoteListCreateView(EstablishmentMixinViews,
lookup_field = 'slug'
serializer_class = serializers.EstablishmentNoteListCreateSerializer
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
def get_object(self):
"""Returns the object the view is displaying."""
establishment_qs = models.Establishment.objects.all()
establishment_qs = super(EstablishmentNoteListCreateView, self).get_queryset()
filtered_establishment_qs = self.filter_queryset(establishment_qs)
establishment = get_object_or_404(filtered_establishment_qs, slug=self.kwargs.get('slug'))
@ -413,10 +461,14 @@ class EstablishmentNoteRUDView(EstablishmentMixinViews,
lookup_field = 'slug'
serializer_class = serializers.EstablishmentNoteBaseSerializer
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager,
)
def get_object(self):
"""Returns the object the view is displaying."""
establishment_qs = models.Establishment.objects.all()
establishment_qs = super(EstablishmentNoteRUDView, self).get_queryset()
filtered_establishment_qs = self.filter_queryset(establishment_qs)
establishment = get_object_or_404(filtered_establishment_qs, slug=self.kwargs.get('slug'))
@ -431,27 +483,39 @@ class EstablishmentNoteRUDView(EstablishmentMixinViews,
class EstablishmentEmployeeCreateView(generics.CreateAPIView):
serializer_class = serializers.EstablishmentEmployeeCreateSerializer
queryset = models.EstablishmentEmployee.objects.all()
# TODO send email to all admins and add endpoint for changing status
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
class EstablishmentEmployeeDeleteView(generics.DestroyAPIView):
queryset = EstablishmentEmployee.objects.all()
permission_classes = [IsEstablishmentManager | permissions.IsAdminUser]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
class EstablishmentPositionListView(generics.ListAPIView):
"""Establishment positions list view."""
pagination_class = None
permission_classes = (permissions.AllowAny,)
queryset = models.Position.objects.all()
serializer_class = serializers.PositionBackSerializer
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
class EstablishmentAdminView(generics.ListAPIView):
"""Establishment admin list view."""
serializer_class = serializers.EstablishmentAdminListSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
def get_queryset(self):
establishment = get_object_or_404(
@ -463,12 +527,18 @@ class MenuDishesListCreateView(generics.ListCreateAPIView):
"""Menu (dessert, main_course, starter) list create view."""
serializer_class = serializers.MenuDishesSerializer
queryset = models.Menu.objects.with_schedule_plates_establishment().dishes().distinct()
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
filter_class = filters.MenuDishesBackFilter
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
class MenuDishesRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Menu (dessert, main_course, starter) RUD view."""
serializer_class = serializers.MenuDishesRUDSerializers
queryset = models.Menu.objects.dishes().distinct()
permission_classes = [IsWineryWineInspector | IsEstablishmentManager]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)

View File

@ -1,30 +1,45 @@
"""Views for app favorites."""
from rest_framework import generics
from establishment.models import Establishment
from establishment.filters import EstablishmentFilter
from establishment.serializers import EstablishmentBaseSerializer, EstablishmentSimilarSerializer
from establishment.models import Establishment
from establishment.serializers import EstablishmentSimilarSerializer
from news.filters import NewsListFilterSet
from news.models import News
from news.serializers import NewsBaseSerializer, NewsListSerializer
from news.serializers import NewsListSerializer
from product.filters import ProductFilterSet
from product.models import Product
from product.serializers import ProductBaseSerializer
from product.filters import ProductFilterSet
from .models import Favorites
from utils.methods import get_permission_classes
from utils.permissions import (
IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector,
IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager,
IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector,
IsGuest, IsModerator, IsProducerFoodInspector,
)
class FavoritesBaseView(generics.GenericAPIView):
"""Base view for Favorites."""
def get_queryset(self):
"""Override get_queryset method."""
return Favorites.objects.by_user(self.request.user)
class FavoritesPermissionMixin:
"""Permissions for application favorites."""
permission_classes = get_permission_classes(
IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector,
IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager,
IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector,
IsModerator, IsProducerFoodInspector,
)
class FavoritesEstablishmentListView(generics.ListAPIView):
class FavoritesEstablishmentListView(FavoritesPermissionMixin, generics.ListAPIView):
"""List views for establishments in favorites."""
serializer_class = EstablishmentSimilarSerializer
filter_class = EstablishmentFilter
permission_classes = get_permission_classes(
IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector,
IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager,
IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector,
IsGuest, IsModerator, IsProducerFoodInspector,
)
def get_queryset(self):
"""Override get_queryset method"""
@ -36,7 +51,7 @@ class FavoritesEstablishmentListView(generics.ListAPIView):
.with_certain_tag_category_related('distillery_type', 'distillery_type')
class FavoritesProductListView(generics.ListAPIView):
class FavoritesProductListView(FavoritesPermissionMixin, generics.ListAPIView):
"""List views for products in favorites."""
serializer_class = ProductBaseSerializer
@ -48,7 +63,7 @@ class FavoritesProductListView(generics.ListAPIView):
.order_by('-favorites')
class FavoritesNewsListView(generics.ListAPIView):
class FavoritesNewsListView(FavoritesPermissionMixin, generics.ListAPIView):
"""List views for news in favorites."""
serializer_class = NewsListSerializer

View File

@ -3,6 +3,8 @@ from django.db.transaction import on_commit
from rest_framework import generics, status
from rest_framework.response import Response
from utils.methods import get_permission_classes
from utils.permissions import IsContentPageManager
from . import tasks, models, serializers
@ -11,6 +13,9 @@ class ImageBaseView(generics.GenericAPIView):
model = models.Image
queryset = models.Image.objects.all()
serializer_class = serializers.ImageSerializer
permission_classes = get_permission_classes(
IsContentPageManager
)
class ImageListCreateView(ImageBaseView, generics.ListCreateAPIView):

View File

@ -1,45 +1,52 @@
"""Location app views."""
from rest_framework import generics
from django.contrib.postgres.fields.jsonb import KeyTextTransform
from utils.models import get_current_locale
from location import models, serializers
from location.views import common
from utils.permissions import IsCountryAdmin
from utils.views import CreateDestroyGalleryViewMixin
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from django.shortcuts import get_object_or_404
from django.db import IntegrityError
from utils.serializers import ImageBaseSerializer
from location.filters import RegionFilter
from rest_framework import generics
from location import filters
from location import models, serializers
from location.filters import RegionFilter
from location.views import common
from utils.methods import get_permission_classes
from utils.models import get_current_locale
from utils.permissions import (
IsGuest, IsEstablishmentManager, IsEstablishmentAdministrator
)
# Address
class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView):
"""Create view for model Address."""
serializer_class = serializers.AddressDetailSerializer
queryset = models.Address.objects.all()
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model Address."""
serializer_class = serializers.AddressDetailSerializer
queryset = models.Address.objects.all()
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
# City
class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView):
"""Create view for model City."""
serializer_class = serializers.CityBaseSerializer
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
queryset = models.City.objects.all()
filter_class = filters.CityBackFilter
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
def get_queryset(self):
"""Overridden method 'get_queryset'."""
@ -53,18 +60,26 @@ class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView):
class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView):
"""Create view for model City."""
serializer_class = serializers.CityBaseSerializer
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
queryset = models.City.objects.all()\
.annotate(locale_name=KeyTextTransform(get_current_locale(), 'name_translated'))\
.order_by('locale_name')
filter_class = filters.CityBackFilter
pagination_class = None
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model City."""
serializer_class = serializers.CityDetailSerializer
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
# Region
@ -72,15 +87,23 @@ class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView):
"""Create view for model Region"""
pagination_class = None
serializer_class = serializers.RegionSerializer
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
# ordering_fields = 'name'
filter_class = RegionFilter
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""Retrieve view for model Region"""
serializer_class = serializers.RegionSerializer
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
# Country
@ -91,11 +114,19 @@ class CountryListCreateView(generics.ListCreateAPIView):
.order_by('locale_name')
serializer_class = serializers.CountryBackSerializer
pagination_class = None
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)
class CountryRUDView(generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model Country."""
serializer_class = serializers.CountryBackSerializer
permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
queryset = models.Country.objects.all()
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
IsGuest,
)

View File

@ -1,25 +1,26 @@
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext_lazy as _
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions, status
from rest_framework import generics, status
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from main import serializers
from main.serializers.back import PanelSerializer
from establishment.serializers.back import EmployeeBackSerializers
from establishment.models import Employee
from establishment.serializers.back import EmployeeBackSerializers
from main import serializers
from main import tasks
from main.filters import AwardFilter
from main.models import Award, Footer, PageType, Panel, SiteFeature, Feature, AwardType
from main.serializers.back import PanelSerializer
from main.views import SiteSettingsView, SiteListView
from utils.methods import get_permission_classes
class AwardLstView(generics.ListCreateAPIView):
"""Award list create view."""
queryset = Award.objects.all().with_base_related()
serializer_class = serializers.BackAwardSerializer
permission_classes = (permissions.IsAdminUser,)
permission_classes = get_permission_classes()
filterset_class = AwardFilter
@ -27,10 +28,10 @@ class AwardCreateAndBind(generics.CreateAPIView):
"""Award create and bind to employee by id"""
queryset = Award.objects.all().with_base_related()
serializer_class = serializers.BackAwardEmployeeCreateSerializer
permission_classes = (permissions.IsAdminUser, )
permission_classes = get_permission_classes()
def create(self, request, *args, **kwargs):
"""!!!Overriden!!!"""
"""Overridden create method."""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
@ -43,7 +44,7 @@ class AwardRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Award RUD view."""
queryset = Award.objects.all().with_base_related()
serializer_class = serializers.BackAwardSerializer
permission_classes = (permissions.IsAdminUser,)
permission_classes = get_permission_classes()
lookup_field = 'id'
@ -52,14 +53,14 @@ class AwardTypesListView(generics.ListAPIView):
pagination_class = None
queryset = AwardType.objects.all()
serializer_class = serializers.AwardTypeBaseSerializer
permission_classes = (permissions.AllowAny, )
permission_classes = get_permission_classes()
class ContentTypeView(generics.ListAPIView):
"""ContentType list view"""
queryset = ContentType.objects.all()
serializer_class = serializers.ContentTypeBackSerializer
permission_classes = (permissions.IsAdminUser,)
permission_classes = get_permission_classes()
filter_backends = (DjangoFilterBackend, )
ordering_fields = '__all__'
lookup_field = 'id'
@ -74,6 +75,7 @@ class FeatureBackView(generics.ListCreateAPIView):
"""Feature list or create View."""
serializer_class = serializers.FeatureSerializer
queryset = Feature.objects.all()
permission_classes = get_permission_classes()
class SiteFeatureBackView(generics.ListCreateAPIView):
@ -81,79 +83,75 @@ class SiteFeatureBackView(generics.ListCreateAPIView):
serializer_class = serializers.SiteFeatureSerializer
queryset = SiteFeature.objects.all()
pagination_class = None
permission_classes = [permissions.IsAdminUser]
permission_classes = get_permission_classes()
class FeatureRUDBackView(generics.RetrieveUpdateDestroyAPIView):
"""Feature RUD View."""
serializer_class = serializers.FeatureSerializer
queryset = SiteFeature.objects.all()
permission_classes = [permissions.IsAdminUser]
permission_classes = get_permission_classes()
class SiteFeatureRUDBackView(generics.RetrieveUpdateDestroyAPIView):
"""Feature RUD View."""
serializer_class = serializers.SiteFeatureSerializer
queryset = SiteFeature.objects.all()
permission_classes = [permissions.IsAdminUser]
permission_classes = get_permission_classes()
class SiteSettingsBackOfficeView(SiteSettingsView):
"""Site settings View."""
serializer_class = serializers.SiteSerializer
permission_classes = get_permission_classes()
class SiteListBackOfficeView(SiteListView):
"""Site settings View."""
serializer_class = serializers.SiteSerializer
permission_classes = get_permission_classes()
class FooterBackView(generics.ListCreateAPIView):
"""Footer back list/create view."""
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
serializer_class = serializers.FooterBackSerializer
queryset = Footer.objects.all()
permission_classes = get_permission_classes()
class FooterRUDBackView(generics.RetrieveUpdateDestroyAPIView):
"""Footer back RUD view."""
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
serializer_class = serializers.FooterBackSerializer
queryset = Footer.objects.all()
permission_classes = get_permission_classes()
class PageTypeListCreateView(generics.ListCreateAPIView):
"""PageType back office view."""
permission_classes = (permissions.IsAuthenticatedOrReadOnly, )
pagination_class = None
serializer_class = serializers.PageTypeBaseSerializer
queryset = PageType.objects.all()
permission_classes = get_permission_classes()
class PanelsListCreateView(generics.ListCreateAPIView):
"""Custom panels view."""
permission_classes = (
permissions.IsAdminUser,
)
serializer_class = PanelSerializer
queryset = Panel.objects.all()
permission_classes = get_permission_classes()
class PanelsRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Custom panels view."""
permission_classes = (
permissions.IsAdminUser,
)
serializer_class = PanelSerializer
queryset = Panel.objects.all()
permission_classes = get_permission_classes()
class PanelsExecuteView(generics.ListAPIView):
"""Custom panels view."""
permission_classes = (
permissions.IsAdminUser,
)
queryset = Panel.objects.all()
permission_classes = get_permission_classes()
def list(self, request, *args, **kwargs):
panel = get_object_or_404(Panel, id=self.kwargs['pk'])
@ -162,8 +160,8 @@ class PanelsExecuteView(generics.ListAPIView):
class PanelsExportCSVView(PanelsExecuteView):
"""Export panels via csv view."""
permission_classes = (permissions.IsAdminUser,)
queryset = Panel.objects.all()
permission_classes = get_permission_classes()
def list(self, request, *args, **kwargs):
panel = get_object_or_404(Panel, id=self.kwargs['pk'])
@ -178,8 +176,8 @@ class PanelsExportCSVView(PanelsExecuteView):
class PanelsExecuteXLSView(PanelsExecuteView):
"""Export panels via xlsx view."""
permission_classes = (permissions.IsAdminUser,)
queryset = Panel.objects.all()
permission_classes = get_permission_classes()
def list(self, request, *args, **kwargs):
panel = get_object_or_404(Panel, id=self.kwargs['pk'])

View File

@ -3,15 +3,17 @@ from django.conf import settings
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.utils import translation
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions, response
from rest_framework.filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from news import filters, models, serializers
from rating.tasks import add_rating
from utils.permissions import IsCountryAdmin, IsContentPageManager, IsReviewManager
from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, CarouselCreateDestroyMixinView
from utils.serializers import ImageBaseSerializer, EmptySerializer
from utils.methods import get_permission_classes
from utils.permissions import IsContentPageManager
from utils.serializers import ImageBaseSerializer
from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, \
CarouselCreateDestroyMixinView
class NewsMixinView:
@ -106,7 +108,7 @@ class NewsTypeListView(generics.ListAPIView):
class NewsBackOfficeMixinView:
"""News back office mixin view."""
permission_classes = (permissions.IsAuthenticated,)
permission_classes = get_permission_classes(IsContentPageManager, IsContentPageManager)
def get_queryset(self):
"""Override get_queryset method."""
@ -124,11 +126,6 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView,
filter_class = filters.NewsListFilterSet
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
filter_backends = (OrderingFilter, DjangoFilterBackend)
permission_classes = [
IsCountryAdmin |
IsContentPageManager |
IsReviewManager
]
ordering_fields = '__all__'
@ -205,9 +202,7 @@ class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView,
class NewsBackOfficeRUDView(NewsBackOfficeMixinView,
generics.RetrieveUpdateDestroyAPIView):
"""Resource for detailed information about news for back-office users."""
serializer_class = serializers.NewsBackOfficeDetailSerializer
permission_classes = [IsCountryAdmin | IsContentPageManager]
def get(self, request, pk, *args, **kwargs):
add_rating(remote_addr=request.META.get('REMOTE_ADDR'),

View File

@ -6,11 +6,11 @@ from rest_framework.response import Response
from notification import models
from notification.serializers import common as serializers
from utils.methods import get_user_ip
from utils.permissions import IsAuthenticatedAndTokenIsValid
class CreateSubscribeView(generics.CreateAPIView):
"""Create subscribe View."""
queryset = models.Subscriber.objects.all()
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.CreateAndUpdateSubscribeSerializer
@ -18,7 +18,6 @@ class CreateSubscribeView(generics.CreateAPIView):
class UpdateSubscribeView(generics.UpdateAPIView):
"""Subscribe info view."""
lookup_field = 'update_code'
lookup_url_kwarg = 'code'
permission_classes = (permissions.AllowAny,)
@ -28,7 +27,6 @@ class UpdateSubscribeView(generics.UpdateAPIView):
class SubscribeInfoView(generics.RetrieveAPIView):
"""Subscribe info view."""
lookup_field = 'update_code'
lookup_url_kwarg = 'code'
permission_classes = (permissions.AllowAny,)
@ -38,8 +36,7 @@ class SubscribeInfoView(generics.RetrieveAPIView):
class SubscribeInfoAuthUserView(generics.RetrieveAPIView):
"""Subscribe info auth user view."""
permission_classes = (permissions.IsAuthenticated,)
permission_classes = (IsAuthenticatedAndTokenIsValid,)
serializer_class = serializers.SubscribeSerializer
lookup_field = None
@ -62,7 +59,6 @@ class SubscribeInfoAuthUserView(generics.RetrieveAPIView):
class UnsubscribeView(generics.UpdateAPIView):
"""Unsubscribe view."""
lookup_field = 'update_code'
lookup_url_kwarg = 'code'
permission_classes = (permissions.AllowAny,)
@ -78,8 +74,7 @@ class UnsubscribeView(generics.UpdateAPIView):
class UnsubscribeAuthUserView(generics.GenericAPIView):
"""Unsubscribe auth user view."""
permission_classes = (permissions.IsAuthenticated,)
permission_classes = (IsAuthenticatedAndTokenIsValid,)
queryset = models.Subscriber.objects.all()
serializer_class = serializers.SubscribeSerializer

View File

@ -1,9 +1,10 @@
from django_filters.rest_framework import DjangoFilterBackend, filters
from rest_framework import generics, permissions
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics
from partner.models import Partner
from partner.serializers import back as serializers
from utils.permissions import IsEstablishmentManager
from utils.methods import get_permission_classes
from utils.permissions import IsEstablishmentManager, IsEstablishmentAdministrator
class PartnerLstView(generics.ListCreateAPIView):
@ -11,8 +12,11 @@ class PartnerLstView(generics.ListCreateAPIView):
queryset = Partner.objects.all()
serializer_class = serializers.BackPartnerSerializer
pagination_class = None
permission_classes = [permissions.IsAdminUser | IsEstablishmentManager]
filter_backends = (DjangoFilterBackend,)
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
filterset_fields = (
'establishment',
'type',
@ -23,5 +27,8 @@ class PartnerRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Partner RUD view."""
queryset = Partner.objects.all()
serializer_class = serializers.BackPartnerSerializer
permission_classes = [permissions.IsAdminUser | IsEstablishmentManager]
lookup_field = 'id'
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)

View File

@ -9,15 +9,14 @@ from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import Case, When, F
from django.utils.translation import gettext_lazy as _
from django.db.models import Subquery
from location.models import WineOriginAddressMixin
from review.models import Review
from utils.methods import transform_into_readable_str
from utils.models import (BaseAttributes, ProjectBaseMixin, HasTagsMixin,
TranslatedFieldsMixin, TJSONField, FavoritesMixin,
GalleryMixin, IntermediateGalleryModelMixin,
TypeDefaultImageMixin)
from utils.methods import transform_into_readable_str
class ProductType(TypeDefaultImageMixin, TranslatedFieldsMixin, ProjectBaseMixin):
@ -229,21 +228,26 @@ class ProductQuerySet(models.QuerySet):
'id')
def available_products(self, user):
"""Return QuerySet with products that is available for editing."""
"""Return QuerySet with establishment that user has an access."""
from account.models import UserRole
available_ids = Subquery(
UserRole.objects.filter(user=user)
.distinct('user', 'establishment')
.values_list('establishment__products', flat=True)
)
return self.filter(id__in=available_ids)
administrator_establishment_ids = []
filters = {}
def available_objects(self, user):
access_roles = user.userrole_set.has_access_to_products()
if access_roles.exists():
return self.available_products(user)
return self.none()
# put in array administrated establishment ids
if user.is_establishment_administrator:
administrator_establishment_ids.extend(
UserRole.objects.filter(user=user)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
)
# check if user is_staff
if not user.is_staff:
filters.update({'establishment__address__city__country__code__in': user.administrated_country_codes})
return self.filter(**filters).union(
self.filter(establishment__id__in=administrator_establishment_ids)
)
class Product(GalleryMixin, TranslatedFieldsMixin, BaseAttributes,

View File

@ -1,12 +1,12 @@
"""Product app back-office views."""
from django.shortcuts import get_object_or_404
from rest_framework import generics, status, permissions, views
from rest_framework import generics, status
from rest_framework.response import Response
from product import serializers, models
from product.views import ProductBaseView
from utils.methods import get_permission_classes
from utils.permissions import (
IsDistilleryLiquorInspector, IsProducerFoodInspector,
IsEstablishmentManager, IsEstablishmentAdministrator)
from utils.serializers import ImageBaseSerializer
from utils.views import CreateDestroyGalleryViewMixin
@ -14,41 +14,36 @@ from utils.views import CreateDestroyGalleryViewMixin
class ProductBackOfficeMixinView(ProductBaseView):
"""Product back-office mixin view."""
permission_classes = (permissions.IsAuthenticated, )
permission_classes = get_permission_classes(
IsEstablishmentAdministrator,
IsEstablishmentManager
)
def get_queryset(self):
"""Override get_queryset method."""
qs = models.Product.objects.with_extended_related().annotate_in_favorites(self.request.user)
return qs
queryset = (
models.Product.objects.with_base_related()
.with_extended_related()
.annotate_in_favorites(self.request.user)
)
if hasattr(self, 'request') and \
(hasattr(self.request, 'user') and hasattr(self.request, 'country_code')):
return queryset.available_products(self.request.user)
return queryset.none()
class ProductTypeBackOfficeMixinView:
"""Product type back-office mixin view."""
permission_classes = (permissions.IsAuthenticated,)
permission_classes = get_permission_classes()
queryset = models.ProductType.objects.all()
class ProductSubTypeBackOfficeMixinView:
"""Product sub type back-office mixin view."""
permission_classes = (permissions.IsAuthenticated,)
permission_classes = get_permission_classes()
queryset = models.ProductSubType.objects.all()
class BackOfficeListCreateMixin(views.APIView):
"""Back-office list-create mixin view."""
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
if self.request.method != 'GET':
super().check_permissions(request)
class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView,
CreateDestroyGalleryViewMixin):
"""Resource for a create gallery for product for back-office users."""
@ -58,7 +53,7 @@ class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView,
"""
Returns the object the view is displaying.
"""
product_qs = self.filter_queryset(self.get_queryset())
product_qs = self.get_queryset()
product = get_object_or_404(product_qs, pk=self.kwargs.get('pk'))
gallery = get_object_or_404(product.product_gallery, image_id=self.kwargs.get('image_id'))
@ -73,7 +68,6 @@ class ProductBackOfficeGalleryListView(ProductBackOfficeMixinView,
generics.ListAPIView):
"""Resource for returning gallery for product for back-office users."""
serializer_class = ImageBaseSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_object(self):
"""Override get_object method."""
@ -94,40 +88,21 @@ class ProductDetailBackOfficeView(ProductBackOfficeMixinView,
generics.RetrieveUpdateDestroyAPIView):
"""Product back-office R/U/D view."""
serializer_class = serializers.ProductBackOfficeDetailSerializer
permission_classes = [
# IsLiquorReviewer |
# IsProductReviewer |
IsEstablishmentManager |
IsEstablishmentAdministrator
]
class ProductListCreateBackOfficeView(ProductBackOfficeMixinView,
generics.ListCreateAPIView):
"""Product back-office list-create view."""
serializer_class = serializers.ProductBackOfficeDetailSerializer
permission_classes = [
IsDistilleryLiquorInspector |
IsProducerFoodInspector |
IsEstablishmentAdministrator |
IsEstablishmentManager
]
def get_queryset(self):
"""Overridden get_queryset method."""
qs = super(ProductListCreateBackOfficeView, self).get_queryset()
return qs.available_objects(self.request.user)
class ProductTypeListCreateBackOfficeView(BackOfficeListCreateMixin,
ProductTypeBackOfficeMixinView,
class ProductTypeListCreateBackOfficeView(ProductTypeBackOfficeMixinView,
generics.ListCreateAPIView):
"""Product type back-office list-create view."""
serializer_class = serializers.ProductTypeBackOfficeDetailSerializer
class ProductTypeRUDBackOfficeView(BackOfficeListCreateMixin,
ProductTypeBackOfficeMixinView,
class ProductTypeRUDBackOfficeView(ProductTypeBackOfficeMixinView,
generics.RetrieveUpdateDestroyAPIView):
"""Product type back-office retrieve-update-destroy view."""
serializer_class = serializers.ProductTypeBackOfficeDetailSerializer
@ -143,22 +118,19 @@ class ProductTypeTagCategoryCreateBackOfficeView(ProductTypeBackOfficeMixinView,
return Response(status=status.HTTP_201_CREATED)
class ProductSubTypeListCreateBackOfficeView(BackOfficeListCreateMixin,
ProductSubTypeBackOfficeMixinView,
class ProductSubTypeListCreateBackOfficeView(ProductSubTypeBackOfficeMixinView,
generics.ListCreateAPIView):
"""Product sub type back-office list-create view."""
serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer
class ProductSubTypeRUDBackOfficeView(BackOfficeListCreateMixin,
ProductSubTypeBackOfficeMixinView,
class ProductSubTypeRUDBackOfficeView(ProductSubTypeBackOfficeMixinView,
generics.RetrieveUpdateDestroyAPIView):
"""Product sub type back-office retrieve-update-destroy view."""
serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer
class ProductNoteListCreateView(ProductBackOfficeMixinView,
BackOfficeListCreateMixin,
generics.ListCreateAPIView):
"""Retrieve|Update|Destroy product note view."""
@ -166,7 +138,7 @@ class ProductNoteListCreateView(ProductBackOfficeMixinView,
def get_object(self):
"""Returns the object the view is displaying."""
product_qs = models.Product.objects.all()
product_qs = super(ProductNoteListCreateView, self).get_queryset()
filtered_product_qs = self.filter_queryset(product_qs)
product = get_object_or_404(filtered_product_qs, pk=self.kwargs.get('pk'))
@ -182,7 +154,6 @@ class ProductNoteListCreateView(ProductBackOfficeMixinView,
class ProductNoteRUDView(ProductBackOfficeMixinView,
BackOfficeListCreateMixin,
generics.RetrieveUpdateDestroyAPIView):
"""Create|Retrieve|Update|Destroy product note view."""
@ -190,7 +161,7 @@ class ProductNoteRUDView(ProductBackOfficeMixinView,
def get_object(self):
"""Returns the object the view is displaying."""
product_qs = models.Product.objects.all()
product_qs = super(ProductNoteRUDView, self).get_queryset()
filtered_product_qs = self.filter_queryset(product_qs)
product = get_object_or_404(filtered_product_qs, pk=self.kwargs.get('pk'))

View File

@ -1,16 +1,18 @@
"""Recipe app common views."""
from django.utils import translation
from rest_framework import generics, permissions
from rest_framework import generics
from recipe import models
from recipe.serializers import common as serializers
from utils.methods import get_permission_classes
from utils.permissions import IsContentPageManager
class RecipeViewMixin(generics.GenericAPIView):
"""Recipe view mixin."""
pagination_class = None
permission_classes = (permissions.AllowAny,)
permission_classes = get_permission_classes(IsContentPageManager)
def get_queryset(self, *args, **kwargs):
user = self.request.user

View File

@ -1,11 +1,8 @@
"""Review app models."""
from pprint import pprint
from django.contrib.contenttypes import fields as generic
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.db.models.signals import post_init, post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from utils.models import (BaseAttributes, TranslatedFieldsMixin,
@ -16,6 +13,15 @@ from utils.models import (BaseAttributes, TranslatedFieldsMixin,
class ReviewQuerySet(models.QuerySet):
"""QuerySets for model Review"""
def with_base_related(self):
"""Return QuerySet with base related."""
return self.select_related(
'reviewer',
'country',
'child',
'content_type',
)
def by_reviewer(self, user):
"""Return reviews by user"""
return self.filter(reviewer=user)

View File

@ -1,21 +1,30 @@
from rest_framework import generics, permissions
from rest_framework import generics
from review import filters
from review import models
from review import serializers
from utils.permissions import IsReviewManager, IsRestaurantInspector
from review.serializers.back import ReviewBackSerializer
from utils.methods import get_permission_classes
from utils.permissions import (
IsReviewManager, IsRestaurantInspector, IsWineryWineInspector,
IsArtisanInspector, IsProducerFoodInspector, IsDistilleryLiquorInspector,
)
class PermissionMixinView:
"""Permission mixin view."""
permission_classes = get_permission_classes(
IsReviewManager, IsRestaurantInspector, IsWineryWineInspector,
IsArtisanInspector, IsProducerFoodInspector, IsDistilleryLiquorInspector,
)
class ReviewMixinView:
"""Review mixin."""
def get_queryset(self):
"""Overridden method 'get_queryset'."""
return models.Review.objects.all()
queryset = models.Review.objects.with_base_related()
class ReviewListView(ReviewMixinView, generics.ListCreateAPIView):
class ReviewListView(PermissionMixinView, ReviewMixinView, generics.ListCreateAPIView):
"""Review list create view.
status values:
@ -25,16 +34,10 @@ class ReviewListView(ReviewMixinView, generics.ListCreateAPIView):
READY = 2
"""
serializer_class = ReviewBackSerializer
queryset = models.Review.objects.all()
permission_classes = [permissions.IsAuthenticatedOrReadOnly, ]
filterset_class = filters.ReviewFilter
def get_queryset(self):
"""Overridden get_queryset method."""
return super(ReviewListView, self).get_queryset()
class ReviewRUDView(generics.RetrieveUpdateDestroyAPIView):
class ReviewRUDView(PermissionMixinView, ReviewMixinView, generics.RetrieveUpdateDestroyAPIView):
"""Review RUD view.
status values:
@ -44,17 +47,14 @@ class ReviewRUDView(generics.RetrieveUpdateDestroyAPIView):
READY = 2
"""
serializer_class = ReviewBackSerializer
queryset = models.Review.objects.all()
permission_classes = [permissions.IsAdminUser | IsReviewManager | IsRestaurantInspector]
lookup_field = 'id'
class InquiriesListView(generics.ListCreateAPIView):
class InquiriesListView(PermissionMixinView, generics.ListCreateAPIView):
"""Inquiries list create view."""
serializer_class = serializers.InquiriesBaseSerializer
queryset = models.Inquiries.objects.all()
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get_queryset(self):
review_id = self.kwargs.get('review_id')
@ -63,19 +63,17 @@ class InquiriesListView(generics.ListCreateAPIView):
return super().get_queryset()
class InquiriesRUDView(generics.RetrieveUpdateDestroyAPIView):
class InquiriesRUDView(PermissionMixinView, generics.RetrieveUpdateDestroyAPIView):
"""Inquiries RUD view."""
serializer_class = serializers.InquiriesBaseSerializer
queryset = models.Inquiries.objects.all()
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
lookup_field = 'id'
class GridItemsListView(generics.ListCreateAPIView):
class GridItemsListView(PermissionMixinView, generics.ListCreateAPIView):
"""GridItems list create view."""
serializer_class = serializers.GridItemsBaseSerializer
queryset = models.GridItems.objects.all()
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get_queryset(self):
inquiry_id = self.kwargs.get('inquiry_id')
@ -84,9 +82,8 @@ class GridItemsListView(generics.ListCreateAPIView):
return super().get_queryset()
class GridItemsRUDView(generics.RetrieveUpdateDestroyAPIView):
class GridItemsRUDView(PermissionMixinView, generics.RetrieveUpdateDestroyAPIView):
"""GridItems RUD view."""
serializer_class = serializers.GridItemsBaseSerializer
queryset = models.GridItems.objects.all()
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
lookup_field = 'id'

View File

@ -4,6 +4,7 @@ from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext_lazy as _
from rest_framework import generics, mixins, permissions, status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework.serializers import ValidationError
@ -11,6 +12,9 @@ from location.models import WineRegion
from product.models import ProductType
from search_indexes import views as search_views
from tag import filters, models, serializers
from utils.permissions import (
IsEstablishmentManager
)
class ChosenTagsView(generics.ListAPIView, viewsets.GenericViewSet):
@ -334,7 +338,9 @@ class TagBackOfficeViewSet(mixins.ListModelMixin, mixins.CreateModelMixin,
"""List/create tag view."""
pagination_class = None
permission_classes = (permissions.IsAdminUser,)
permission_classes = [
IsAdminUser, IsEstablishmentManager
]
queryset = models.Tag.objects.with_base_related()
serializer_class = serializers.TagBackOfficeSerializer
bind_object_serializer_class = serializers.TagBindObjectSerializer
@ -388,10 +394,12 @@ class TagCategoryBackOfficeViewSet(mixins.CreateModelMixin,
TagCategoryViewSet):
"""ViewSet for TagCategory model for BackOffice users."""
permission_classes = (permissions.IsAdminUser,)
queryset = TagCategoryViewSet.queryset.with_extended_related()
serializer_class = serializers.TagCategoryBackOfficeDetailSerializer
bind_object_serializer_class = serializers.TagCategoryBindObjectSerializer
permission_classes = [
IsAdminUser, IsEstablishmentManager
]
def perform_binding(self, serializer):
data = serializer.validated_data

View File

@ -8,12 +8,12 @@ from functools import reduce
from io import BytesIO
import requests
from PIL import Image
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.gis.geos import Point
from django.http.request import HttpRequest
from django.utils.timezone import datetime
from PIL import Image
from rest_framework import status
from rest_framework.request import Request
@ -216,3 +216,17 @@ def get_image_meta_by_url(url) -> (int, int, int):
image = Image.open(BytesIO(image_raw.content))
width, height = image.size
return int(image_raw.headers.get('content-length')), width, height
def get_permission_classes(*args) -> list:
"""Return permission_class object with admin permissions."""
from rest_framework.permissions import IsAdminUser
from utils.permissions import IsCountryAdmin
admin_permission_classes = [IsCountryAdmin, IsAdminUser]
permission_classes = [
reduce(
lambda a, b: a | b, admin_permission_classes + list(args)
)
]
return permission_classes

View File

@ -65,11 +65,8 @@ class IsGuest(permissions.IsAuthenticatedOrReadOnly):
]
return all(rules)
def has_object_permission(self, request, view, obj):
return self.has_permission(request, view)
class IsApprovedUser(permissions.IsAuthenticated):
class IsApprovedUser(IsAuthenticatedAndTokenIsValid):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
@ -122,7 +119,6 @@ class IsCountryAdmin(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and hasattr(request, 'country_code') and
request.country_code):
role = Role.objects.filter(
@ -148,7 +144,6 @@ class IsModerator(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and hasattr(request, 'country_code') and
request.country_code):
role = Role.objects.filter(
@ -170,7 +165,6 @@ class IsEstablishmentManager(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -194,7 +188,6 @@ class IsEstablishmentAdministrator(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -243,7 +236,6 @@ class IsReviewManager(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -277,7 +269,6 @@ class IsRestaurantInspector(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -311,7 +302,6 @@ class IsArtisanInspector(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -345,7 +335,6 @@ class IsWineryWineInspector(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -379,7 +368,6 @@ class IsProducerFoodInspector(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):
@ -413,7 +401,6 @@ class IsDistilleryLiquorInspector(IsApprovedUser):
super().has_permission(request, view)
]
has_permission = False
# check role
if (request.user.is_authenticated and
hasattr(request, 'country_code') and
request.country_code):