diff --git a/apps/account/serializers/web.py b/apps/account/serializers/web.py index d325cea6..8d6fadf7 100644 --- a/apps/account/serializers/web.py +++ b/apps/account/serializers/web.py @@ -1,6 +1,5 @@ """Serializers for account web""" from django.contrib.auth import password_validation as password_validators -from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from account import models @@ -25,7 +24,7 @@ class PasswordResetSerializer(serializers.Serializer): if not user.is_authenticated: if not username_or_email: - raise serializers.ValidationError(_('username or email not in request body.')) + raise utils_exceptions.UserNotFoundError() filters = {} if username_validator(username_or_email): diff --git a/apps/authorization/views/common.py b/apps/authorization/views/common.py index 98f79bd9..4231ed7a 100644 --- a/apps/authorization/views/common.py +++ b/apps/authorization/views/common.py @@ -116,7 +116,7 @@ class OAuth2SignUpView(OAuth2ViewMixin, JWTGenericViewMixin): source = serializer.validated_data.get('source') request_data.update({ 'grant_type': settings.OAUTH2_SOCIAL_AUTH_GRANT_TYPE, - 'backend': settings.OAUTH2_SOCIAL_AUTH_BACKEND_NAME + 'backend': settings.OAUTH2_SOCIAL_AUTH_BACKEND_NAME, }) # Use the rest framework `.data` to fake the post body of the django request. diff --git a/apps/location/serializers/__init__.py b/apps/location/serializers/__init__.py new file mode 100644 index 00000000..418d2500 --- /dev/null +++ b/apps/location/serializers/__init__.py @@ -0,0 +1,2 @@ +from location.serializers.common import * +from location.serializers.back import * diff --git a/apps/location/serializers/back.py b/apps/location/serializers/back.py new file mode 100644 index 00000000..f3b36e64 --- /dev/null +++ b/apps/location/serializers/back.py @@ -0,0 +1,22 @@ +from django.contrib.gis.geos import Point +from rest_framework import serializers + +from location import models +from location.serializers import common + + +class AddressCreateSerializer(common.AddressSerializer): + """Address create serializer.""" + + +class CountryBackSerializer(common.CountrySerializer): + """Country back-office serializer.""" + + class Meta: + model = models.Country + fields = [ + 'id', + 'code', + 'svg_image', + 'name', + ] diff --git a/apps/location/serializers.py b/apps/location/serializers/common.py similarity index 71% rename from apps/location/serializers.py rename to apps/location/serializers/common.py index 34d92cc3..839ea8e8 100644 --- a/apps/location/serializers.py +++ b/apps/location/serializers/common.py @@ -23,7 +23,12 @@ class CountrySerializer(serializers.ModelSerializer): class RegionSerializer(serializers.ModelSerializer): """Region serializer""" - country = CountrySerializer() + country = CountrySerializer(read_only=True) + country_id = serializers.PrimaryKeyRelatedField( + source='country', + queryset=models.Country.objects.all(), + write_only=True + ) class Meta: model = models.Region @@ -32,13 +37,24 @@ class RegionSerializer(serializers.ModelSerializer): 'name', 'code', 'parent_region', - 'country' + 'country', + 'country_id' ] class CitySerializer(serializers.ModelSerializer): """City serializer.""" - region = RegionSerializer() + region = RegionSerializer(read_only=True) + region_id = serializers.PrimaryKeyRelatedField( + source='region', + queryset=models.Region.objects.all(), + write_only=True + ) + country_id = serializers.PrimaryKeyRelatedField( + source='country', + queryset=models.Country.objects.all(), + write_only=True + ) class Meta: model = models.City @@ -47,6 +63,8 @@ class CitySerializer(serializers.ModelSerializer): 'name', 'code', 'region', + 'region_id', + 'country_id', 'postal_code', 'is_island', ] @@ -54,13 +72,18 @@ class CitySerializer(serializers.ModelSerializer): class AddressSerializer(serializers.ModelSerializer): """Address serializer.""" - city = CitySerializer() + city_id = serializers.PrimaryKeyRelatedField( + source='city', + queryset=models.City.objects.all()) + city = CitySerializer(read_only=True) geo_lon = serializers.FloatField(allow_null=True) geo_lat = serializers.FloatField(allow_null=True) class Meta: model = models.Address fields = [ + 'id', + 'city_id', 'city', 'street_name_1', 'street_name_2', @@ -74,9 +97,10 @@ class AddressSerializer(serializers.ModelSerializer): # if geo_lat and geo_lon was sent geo_lat = attrs.pop('geo_lat') if 'geo_lat' in attrs else None geo_lon = attrs.pop('geo_lon') if 'geo_lon' in attrs else None + if geo_lat and geo_lon: # Point(longitude, latitude) - attrs['location'] = Point(geo_lat, geo_lon) + attrs['coordinates'] = Point(geo_lat, geo_lon) return attrs def to_representation(self, instance): diff --git a/apps/location/urls/__init__.py b/apps/location/urls/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/location/urls/back.py b/apps/location/urls/back.py new file mode 100644 index 00000000..8fd87dc9 --- /dev/null +++ b/apps/location/urls/back.py @@ -0,0 +1,20 @@ +"""Location app back-office urlconf.""" +from django.urls import path + +from location import views + +app_name = 'location' + +urlpatterns = [ + path('addresses/', views.AddressListCreateView.as_view(), name='address-list-create'), + path('addresses//', views.AddressRUDView.as_view(), name='address-RUD'), + + path('cities/', views.CityListCreateView.as_view(), name='city-list-create'), + path('cities//', views.CityRUDView.as_view(), name='city-retrieve'), + + path('countries/', views.CountryListCreateView.as_view(), name='country-list-create'), + path('countries//', views.CountryRUDView.as_view(), name='country-retrieve'), + + path('regions/', views.RegionListCreateView.as_view(), name='region-list-create'), + path('regions//', views.RegionRUDView.as_view(), name='region-retrieve'), +] diff --git a/apps/location/urls.py b/apps/location/urls/common.py similarity index 95% rename from apps/location/urls.py rename to apps/location/urls/common.py index 0630db93..3b73f607 100644 --- a/apps/location/urls.py +++ b/apps/location/urls/common.py @@ -1,4 +1,4 @@ -"""Location app urlconf.""" +"""Location app common urlconf.""" from django.urls import path from location import views diff --git a/apps/location/urls/mobile.py b/apps/location/urls/mobile.py new file mode 100644 index 00000000..b808d5b6 --- /dev/null +++ b/apps/location/urls/mobile.py @@ -0,0 +1,7 @@ +"""Location app mobile urlconf.""" +from location.urls.common import urlpatterns as common_urlpatterns + + +urlpatterns = [] + +urlpatterns.extend(common_urlpatterns) \ No newline at end of file diff --git a/apps/location/urls/web.py b/apps/location/urls/web.py new file mode 100644 index 00000000..cac89037 --- /dev/null +++ b/apps/location/urls/web.py @@ -0,0 +1,7 @@ +"""Location app web urlconf.""" +from location.urls.common import urlpatterns as common_urlpatterns + + +urlpatterns = [] + +urlpatterns.extend(common_urlpatterns) \ No newline at end of file diff --git a/apps/location/views/__init__.py b/apps/location/views/__init__.py new file mode 100644 index 00000000..ab091325 --- /dev/null +++ b/apps/location/views/__init__.py @@ -0,0 +1,2 @@ +from location.views.common import * +from location.views.back import * diff --git a/apps/location/views/back.py b/apps/location/views/back.py new file mode 100644 index 00000000..69ec28bc --- /dev/null +++ b/apps/location/views/back.py @@ -0,0 +1,53 @@ +"""Location app views.""" +from rest_framework import generics +from rest_framework import permissions + +from location import models, serializers +from location.views import common + + +# Address +class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView): + """Create view for model Address.""" + serializer_class = serializers.AddressSerializer + queryset = models.Address.objects.all() + + +class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView): + """RUD view for model Address.""" + serializer_class = serializers.AddressSerializer + queryset = models.Address.objects.all() + + +# City +class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView): + """Create view for model City.""" + serializer_class = serializers.CitySerializer + + +class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView): + """RUD view for model City.""" + serializer_class = serializers.CitySerializer + + +# Region +class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView): + """Create view for model Region""" + serializer_class = serializers.RegionSerializer + + +class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView): + """Retrieve view for model Region""" + serializer_class = serializers.RegionSerializer + + +# Country +class CountryListCreateView(common.CountryViewMixin, generics.ListCreateAPIView): + """List/Create view for model Country.""" + serializer_class = serializers.CountryBackSerializer + pagination_class = None + + +class CountryRUDView(common.CountryViewMixin, generics.RetrieveUpdateDestroyAPIView): + """RUD view for model Country.""" + serializer_class = serializers.CountryBackSerializer diff --git a/apps/location/views.py b/apps/location/views/common.py similarity index 88% rename from apps/location/views.py rename to apps/location/views/common.py index 52132d28..6bc332ad 100644 --- a/apps/location/views.py +++ b/apps/location/views/common.py @@ -3,11 +3,10 @@ from rest_framework import generics from rest_framework import permissions from location import models, serializers -from utils.views import JWTGenericViewMixin # Mixins -class CountryViewMixin(JWTGenericViewMixin, generics.GenericAPIView): +class CountryViewMixin(generics.GenericAPIView): """View Mixin for model Country""" serializer_class = serializers.CountrySerializer @@ -115,13 +114,3 @@ class AddressListView(AddressViewMixin, generics.ListAPIView): 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/views.py b/apps/utils/views.py index 9af89360..8333b34a 100644 --- a/apps/utils/views.py +++ b/apps/utils/views.py @@ -67,7 +67,7 @@ class JWTGenericViewMixin(generics.GenericAPIView): # todo: remove config for develop from os import environ configuration = environ.get('SETTINGS_CONFIGURATION', None) - if configuration == 'development': + if configuration == 'development' or configuration == 'stage': response.set_cookie(key=cookie.key, value=cookie.value, secure=cookie.secure, diff --git a/project/settings/base.py b/project/settings/base.py index 71fbf147..1a54b1b7 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -256,6 +256,10 @@ OAUTH2_PROVIDER_APPLICATION_MODEL = 'authorization.Application' # Facebook configuration SOCIAL_AUTH_FACEBOOK_KEY = '386843648701452' SOCIAL_AUTH_FACEBOOK_SECRET = 'a71cf0bf3980843a8f1ea74c6d805fd7' +SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', ] +SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { + 'fields': 'id, name, email', +} # SMS Settings SMS_EXPIRATION = 5 diff --git a/project/templates/account/change_email.html b/project/templates/account/change_email.html index 40c1b227..0a257ed6 100644 --- a/project/templates/account/change_email.html +++ b/project/templates/account/change_email.html @@ -3,7 +3,7 @@ {% trans "Please go to the following page for confirmation new email address:" %} -https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ +https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ {% trans "Thanks for using our site!" %} diff --git a/project/templates/account/password_reset_email.html b/project/templates/account/password_reset_email.html index ee84fd0b..9fb3fbf3 100644 --- a/project/templates/account/password_reset_email.html +++ b/project/templates/account/password_reset_email.html @@ -3,7 +3,7 @@ {% trans "Please go to the following page and choose a new password:" %} -https://{{ country_code }}.{{ domain_uri }}/recovery/{{ uidb64 }}/{{ token }}/ +https://{{ country_code }}.{{ domain_uri }}/recovery/{{ uidb64 }}/{{ token }}/ {% trans "Thanks for using our site!" %} diff --git a/project/templates/authorization/confirm_email.html b/project/templates/authorization/confirm_email.html index f3bbd50e..3e51add7 100644 --- a/project/templates/authorization/confirm_email.html +++ b/project/templates/authorization/confirm_email.html @@ -2,8 +2,7 @@ {% blocktrans %}You're receiving this email because you trying to register new account at {{ site_name }}.{% endblocktrans %} {% trans "Please confirm your email address to complete the registration:" %} - -https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ +https://{{ country_code }}.{{ domain_uri }}/registered/{{ uidb64 }}/{{ token }}/ {% trans "Thanks for using our site!" %} diff --git a/project/urls/back.py b/project/urls/back.py index 6337f4cd..5a64b955 100644 --- a/project/urls/back.py +++ b/project/urls/back.py @@ -5,10 +5,6 @@ app_name = 'back' urlpatterns = [ path('gallery/', include(('gallery.urls', 'gallery'), namespace='gallery')), - # path('account/', include('account.urls.web')), - # path('advertisement/', include('advertisement.urls.web')), - # path('collection/', include('collection.urls.web')), path('establishments/', include('establishment.urls.back')), - # path('news/', include('news.urls.web')), - # path('partner/', include('partner.urls.web')), + path('location/', include('location.urls.back')), ] \ No newline at end of file diff --git a/project/urls/web.py b/project/urls/web.py index 803f7243..9c2a932e 100644 --- a/project/urls/web.py +++ b/project/urls/web.py @@ -25,7 +25,7 @@ urlpatterns = [ path('news/', include('news.urls.web')), path('notifications/', include('notification.urls.web')), path('partner/', include('partner.urls.web')), - path('location/', include('location.urls')), + path('location/', include('location.urls.web')), path('main/', include('main.urls')), path('translation/', include('translation.urls')), path('comments/', include('comment.urls.web')),