From 7fe903b01bd244da9637e2c06380bbf6a10387fe Mon Sep 17 00:00:00 2001 From: Anatoly Date: Wed, 14 Aug 2019 14:00:12 +0300 Subject: [PATCH] version 0.0.8: added CRUD endpoints for models Address, Region, Country and City; also refactored custom permission class --- apps/location/urls.py | 25 ++++++- apps/location/views.py | 138 +++++++++++++++++++++++++++++++++++++- apps/utils/methods.py | 10 +-- apps/utils/permissions.py | 16 +++-- project/urls/__init__.py | 2 + 5 files changed, 177 insertions(+), 14 deletions(-) diff --git a/apps/location/urls.py b/apps/location/urls.py index 41176a1e..ce12d097 100644 --- a/apps/location/urls.py +++ b/apps/location/urls.py @@ -6,4 +6,27 @@ from location import views app_name = 'location' urlpatterns = [ -] \ No newline at end of file + path('country/list/', views.CountryListView.as_view(), name='country-list'), + path('country/create/', views.CountryCreateView.as_view(), name='country-create'), + path('country//detail/', views.CountryRetrieveView.as_view(), name='country-retrieve'), + path('country//delete/', views.CountryDestroyView.as_view(), name='country-destroy'), + path('country//update/', views.CountryUpdateView.as_view(), name='country-update'), + + path('region/list/', views.RegionListView.as_view(), name='region-list'), + path('region/create/', views.RegionCreateView.as_view(), name='region-create'), + path('region//detail/', views.RegionRetrieveView.as_view(), name='region-retrieve'), + path('region//delete/', views.RegionDestroyView.as_view(), name='region-destroy'), + path('region//update/', views.RegionUpdateView.as_view(), name='region-update'), + + path('city/list/', views.CityListView.as_view(), name='city-list'), + path('city/create/', views.CityCreateView.as_view(), name='city-create'), + path('city//detail/', views.CityRetrieveView.as_view(), name='city-retrieve'), + path('city//delete/', views.CityDestroyView.as_view(), name='city-destroy'), + path('city//update/', views.CityUpdateView.as_view(), name='city-update'), + + path('address/list/', views.AddressListView.as_view(), name='address-list'), + path('address/create/', views.AddressCreateView.as_view(), name='address-create'), + path('address//detail/', views.AddressRetrieveView.as_view(), name='address-retrieve'), + path('address//delete/', views.AddressDestroyView.as_view(), name='address-destroy'), + path('address//update/', views.AddressUpdateView.as_view(), name='address-update'), +] diff --git a/apps/location/views.py b/apps/location/views.py index a13db907..b7baa59e 100644 --- a/apps/location/views.py +++ b/apps/location/views.py @@ -1,3 +1,139 @@ -from rest_framework import generics, permissions +from rest_framework import generics +from rest_framework import permissions from location import models, serializers + + +# Mixins +class CountryViewMixin(generics.GenericAPIView): + """View Mixin for model Country""" + model = models.Country + queryset = models.Country.objects.all() + + +class RegionViewMixin(generics.GenericAPIView): + """View Mixin for model Region""" + model = models.Region + queryset = models.Region.objects.all() + + +class CityViewMixin(generics.GenericAPIView): + """View Mixin for model City""" + model = models.City + queryset = models.City.objects.all() + + +class AddressViewMixin(generics.GenericAPIView): + """View Mixin for model Address""" + model = models.Address + queryset = models.Address.objects.all() + + +# Country +class CountryCreateView(CountryViewMixin, generics.CreateAPIView): + """Create view for model Country""" + serializer_class = serializers.CountrySerializer + + +class CountryRetrieveView(CountryViewMixin, generics.RetrieveAPIView): + """Retrieve view for model Country""" + serializer_class = serializers.CountrySerializer + + +class CountryListView(CountryViewMixin, generics.ListAPIView): + """List view for model Country""" + permission_classes = (permissions.AllowAny, ) + serializer_class = serializers.CountrySerializer + + +class CountryDestroyView(CountryViewMixin, generics.DestroyAPIView): + """Destroy view for model Country""" + serializer_class = serializers.CountrySerializer + + +class CountryUpdateView(CountryViewMixin, generics.UpdateAPIView): + """Update view for model Country""" + serializer_class = serializers.CountrySerializer + + +# Region +class RegionCreateView(RegionViewMixin, generics.CreateAPIView): + """Create view for model Region""" + serializer_class = serializers.RegionSerializer + + +class RegionRetrieveView(RegionViewMixin, generics.RetrieveAPIView): + """Retrieve view for model Region""" + serializer_class = serializers.RegionSerializer + + +class RegionListView(RegionViewMixin, generics.ListAPIView): + """List view for model Country""" + permission_classes = (permissions.AllowAny, ) + serializer_class = serializers.CountrySerializer + + +class RegionDestroyView(RegionViewMixin, generics.DestroyAPIView): + """Destroy view for model Country""" + serializer_class = serializers.CountrySerializer + + +class RegionUpdateView(RegionViewMixin, generics.UpdateAPIView): + """Update view for model Country""" + serializer_class = serializers.CountrySerializer + + +# City +class CityCreateView(CityViewMixin, generics.CreateAPIView): + """Create view for model City""" + serializer_class = serializers.CitySerializer + + +class CityRetrieveView(CityViewMixin, generics.RetrieveAPIView): + """Retrieve view for model City""" + serializer_class = serializers.CitySerializer + + +class CityListView(CityViewMixin, generics.ListAPIView): + """List view for model City""" + permission_classes = (permissions.AllowAny, ) + serializer_class = serializers.CitySerializer + + +class CityDestroyView(CityViewMixin, generics.DestroyAPIView): + """Destroy view for model City""" + serializer_class = serializers.CitySerializer + + +class CityUpdateView(CityViewMixin, generics.UpdateAPIView): + """Update view for model City""" + serializer_class = serializers.CitySerializer + + +# Address +class AddressCreateView(AddressViewMixin, generics.CreateAPIView): + """Create view for model Address""" + serializer_class = serializers.AddressSerializer + + +class AddressRetrieveView(AddressViewMixin, generics.RetrieveAPIView): + """Retrieve view for model Address""" + serializer_class = serializers.AddressSerializer + + +class AddressListView(AddressViewMixin, generics.ListAPIView): + """List view for model Address""" + permission_classes = (permissions.AllowAny, ) + serializer_class = serializers.AddressSerializer + + +class AddressDestroyView(AddressViewMixin, generics.DestroyAPIView): + """Destroy view for model Address""" + serializer_class = serializers.AddressSerializer + + +class AddressUpdateView(AddressViewMixin, generics.UpdateAPIView): + """Update view for model Address""" + serializer_class = serializers.AddressSerializer + + diff --git a/apps/utils/methods.py b/apps/utils/methods.py index 20d056be..a14b4460 100644 --- a/apps/utils/methods.py +++ b/apps/utils/methods.py @@ -14,8 +14,8 @@ def generate_code(digits=6, string_output=True): def get_token_from_request(request): """Get access token from request""" - assert isinstance(request, (HttpRequest, Request)) - if isinstance(request, HttpRequest): - return request.headers.get('Authorization').split(' ')[::-1][0] - elif isinstance(request, Request): - return request._request.headers.get('Authorization').split(' ')[::-1][0] + if 'Authorization' in request.headers: + if isinstance(request, HttpRequest): + return request.headers.get('Authorization').split(' ')[::-1][0] + elif isinstance(request, Request): + return request._request.headers.get('Authorization').split(' ')[::-1][0] diff --git a/apps/utils/permissions.py b/apps/utils/permissions.py index 748f1d28..3e4a1d33 100644 --- a/apps/utils/permissions.py +++ b/apps/utils/permissions.py @@ -10,12 +10,14 @@ class IsAuthenticatedAndTokenIsValid(BasePermission): """ def has_permission(self, request, view): - """Check permissions by access token and default rest permission IsAuthenticated""" + """Check permissions by access token and default REST permission IsAuthenticated""" user = request.user - token = get_token_from_request(request) - blacklisted = BlacklistedAccessToken.objects.by_user(user)\ - .by_token(token)\ + if user and user.is_authenticated: + token = get_token_from_request(request) + # Check if user access token not expired + expired = BlacklistedAccessToken.objects.by_token(token)\ + .by_user(user)\ .exists() - return bool(user and - user.is_authenticated and - not blacklisted) + return not expired + else: + return False diff --git a/project/urls/__init__.py b/project/urls/__init__.py index ee6aa906..dae5ef5d 100644 --- a/project/urls/__init__.py +++ b/project/urls/__init__.py @@ -23,6 +23,7 @@ from rest_framework import permissions # URL platform patterns from project.urls import web as web_urlpatterns +from location import urls as location_urls schema_view = get_schema_view( @@ -58,6 +59,7 @@ urlpatterns_auth = [ urlpatterns = [ path('admin/', admin.site.urls), path('api/web/', include(web_urlpatterns)), + path('api/location/', include(location_urls.urlpatterns)), ] urlpatterns = urlpatterns + \