added field phone to User model, change establishment transfer, added filters (full-text search, role_country_code, country_code), change account serializers
This commit is contained in:
parent
6d627ac240
commit
de78ee5d6e
|
|
@ -25,13 +25,13 @@ class UserAdmin(BaseUserAdmin):
|
|||
'is_staff', 'is_superuser', 'email_confirmed')
|
||||
list_filter = ('is_active', 'is_staff', 'is_superuser', 'email_confirmed',
|
||||
'groups',)
|
||||
search_fields = ('email', 'first_name', 'last_name')
|
||||
search_fields = ('email', 'first_name', 'last_name', 'phone',)
|
||||
readonly_fields = ('last_login', 'date_joined', 'image_preview', 'cropped_image_preview', 'last_ip', 'last_country')
|
||||
fieldsets = (
|
||||
(None, {'fields': ('email', 'password',)}),
|
||||
(_('Personal info'), {
|
||||
'fields': ('username', 'first_name', 'last_name',
|
||||
'image_url', 'image_preview',
|
||||
'image_url', 'image_preview', 'phone',
|
||||
'cropped_image_url', 'cropped_image_preview',)}),
|
||||
(_('Subscription'), {
|
||||
'fields': (
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ from account import models
|
|||
class AccountBackOfficeFilter(filters.FilterSet):
|
||||
"""Account filter set."""
|
||||
|
||||
search = filters.CharFilter(method='search_text')
|
||||
role_country_code = filters.CharFilter(method='by_role_country_code')
|
||||
role = filters.MultipleChoiceFilter(choices=models.Role.ROLE_CHOICES,
|
||||
method='filter_by_roles')
|
||||
method='by_roles')
|
||||
|
||||
class Meta:
|
||||
"""Meta class."""
|
||||
|
|
@ -21,9 +23,33 @@ class AccountBackOfficeFilter(filters.FilterSet):
|
|||
'is_staff',
|
||||
'is_active',
|
||||
'is_superuser',
|
||||
'search',
|
||||
'role_country_code',
|
||||
)
|
||||
|
||||
def filter_by_roles(self, queryset, name, value):
|
||||
def by_roles(self, queryset, name, value):
|
||||
if value not in EMPTY_VALUES:
|
||||
return queryset.by_roles(value)
|
||||
return queryset
|
||||
|
||||
def search_text(self, queryset, name, value):
|
||||
if value not in EMPTY_VALUES:
|
||||
return queryset.search_text(value)
|
||||
return queryset
|
||||
|
||||
def by_role_country_code(self, queryset, name, value):
|
||||
if value not in EMPTY_VALUES:
|
||||
return queryset.by_role_country_code(value)
|
||||
return queryset
|
||||
|
||||
|
||||
class RoleListFilter(filters.FilterSet):
|
||||
"""Role filter set."""
|
||||
country_code = filters.CharFilter(field_name='country__code')
|
||||
|
||||
class Meta:
|
||||
"""Meta class."""
|
||||
model = models.Role
|
||||
fields = [
|
||||
'country_code',
|
||||
]
|
||||
|
|
|
|||
19
apps/account/migrations/0033_user_phone.py
Normal file
19
apps/account/migrations/0033_user_phone.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.2.7 on 2020-01-20 09:39
|
||||
|
||||
from django.db import migrations
|
||||
import phonenumber_field.modelfields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0032_auto_20200114_1311'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='phone',
|
||||
field=phonenumber_field.modelfields.PhoneNumberField(blank=True, default=None, max_length=128, null=True, verbose_name='Phone'),
|
||||
),
|
||||
]
|
||||
|
|
@ -20,6 +20,8 @@ from main.models import SiteSettings
|
|||
from utils.models import GMTokenGenerator
|
||||
from utils.models import ImageMixin, ProjectBaseMixin, PlatformMixin
|
||||
from utils.tokens import GMRefreshToken
|
||||
from django.contrib.postgres.search import SearchVector
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
|
||||
class RoleQuerySet(models.QuerySet):
|
||||
|
|
@ -142,6 +144,24 @@ class UserQuerySet(models.QuerySet):
|
|||
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER).first()
|
||||
return self.by_role(role).filter(userrole__establishment=establishment)
|
||||
|
||||
def annotate_search_text(self):
|
||||
"""Full-text search"""
|
||||
return self.annotate(search_text=SearchVector(
|
||||
'username',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone',
|
||||
))
|
||||
|
||||
def search_text(self, value: str):
|
||||
"""Filter by annotated search vector."""
|
||||
return self.annotate_search_text().filter(search_text=value)
|
||||
|
||||
def by_role_country_code(self, country_code: str):
|
||||
"""Filter by role country code."""
|
||||
return self.filter(userrole__role__country__code=country_code).distinct()
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
"""Base user model."""
|
||||
|
|
@ -178,6 +198,8 @@ class User(AbstractUser):
|
|||
default=None,
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
phone = PhoneNumberField(blank=True, null=True, default=None,
|
||||
verbose_name=_('Phone'))
|
||||
|
||||
EMAIL_FIELD = 'email'
|
||||
USERNAME_FIELD = 'email'
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from account import models
|
||||
from account.models import User
|
||||
from account.serializers import RoleBaseSerializer, subscriptions_handler
|
||||
from account.serializers import RoleBaseSerializer, UserSerializer, subscriptions_handler
|
||||
from main.models import SiteSettings
|
||||
|
||||
|
||||
|
|
@ -17,20 +16,12 @@ class _SiteSettingsSerializer(serializers.ModelSerializer):
|
|||
)
|
||||
|
||||
|
||||
class BackUserSerializer(serializers.ModelSerializer):
|
||||
class BackUserSerializer(UserSerializer):
|
||||
|
||||
last_country = _SiteSettingsSerializer(read_only=True)
|
||||
roles = RoleBaseSerializer(many=True, read_only=True)
|
||||
subscriptions = serializers.ListField(
|
||||
source='subscription_types',
|
||||
allow_null=True,
|
||||
allow_empty=True,
|
||||
child=serializers.IntegerField(min_value=1),
|
||||
required=False,
|
||||
help_text='list of subscription_types id',
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
class Meta(UserSerializer.Meta):
|
||||
fields = (
|
||||
'id',
|
||||
'last_login',
|
||||
|
|
@ -54,9 +45,12 @@ class BackUserSerializer(serializers.ModelSerializer):
|
|||
'last_country',
|
||||
'roles',
|
||||
'subscriptions',
|
||||
'phone',
|
||||
'phone_as_international',
|
||||
)
|
||||
extra_kwargs = {
|
||||
'password': {'write_only': True},
|
||||
'phone': {'write_only': True},
|
||||
}
|
||||
read_only_fields = (
|
||||
'old_password',
|
||||
|
|
@ -82,8 +76,7 @@ class BackUserSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class BackDetailUserSerializer(BackUserSerializer):
|
||||
class Meta:
|
||||
model = User
|
||||
class Meta(BackUserSerializer.Meta):
|
||||
fields = (
|
||||
'id',
|
||||
'last_country',
|
||||
|
|
@ -109,6 +102,8 @@ class BackDetailUserSerializer(BackUserSerializer):
|
|||
'groups',
|
||||
'user_permissions',
|
||||
'subscriptions',
|
||||
'phone',
|
||||
'phone_as_international',
|
||||
)
|
||||
read_only_fields = (
|
||||
'old_password',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from notification.models import Subscribe, Subscriber
|
|||
from utils import exceptions as utils_exceptions
|
||||
from utils import methods as utils_methods
|
||||
from utils.methods import generate_string_code
|
||||
from phonenumber_field.serializerfields import PhoneNumberField
|
||||
|
||||
|
||||
def subscriptions_handler(subscriptions_list, user):
|
||||
|
|
@ -43,6 +44,7 @@ class RoleBaseSerializer(serializers.ModelSerializer):
|
|||
"""Serializer for model Role."""
|
||||
role_display = serializers.CharField(source='get_role_display', read_only=True)
|
||||
navigation_bar_permission = NavigationBarPermissionBaseSerializer(read_only=True)
|
||||
country_code = serializers.CharField(source='country.code', read_only=True, allow_null=True)
|
||||
|
||||
class Meta:
|
||||
"""Meta class."""
|
||||
|
|
@ -51,6 +53,7 @@ class RoleBaseSerializer(serializers.ModelSerializer):
|
|||
'id',
|
||||
'role_display',
|
||||
'navigation_bar_permission',
|
||||
'country_code',
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -75,6 +78,9 @@ class UserSerializer(serializers.ModelSerializer):
|
|||
required=False,
|
||||
help_text='list of subscription_types id',
|
||||
)
|
||||
phone_as_international = PhoneNumberField(source='phone.as_international',
|
||||
allow_null=True,
|
||||
read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = models.User
|
||||
|
|
@ -90,6 +96,8 @@ class UserSerializer(serializers.ModelSerializer):
|
|||
'newsletter',
|
||||
'roles',
|
||||
'subscriptions',
|
||||
'phone',
|
||||
'phone_as_international',
|
||||
]
|
||||
extra_kwargs = {
|
||||
'first_name': {'required': False, 'write_only': True, },
|
||||
|
|
@ -98,6 +106,7 @@ class UserSerializer(serializers.ModelSerializer):
|
|||
'image_url': {'required': False, },
|
||||
'cropped_image_url': {'required': False, },
|
||||
'newsletter': {'required': False, },
|
||||
'phone': {'required': False, 'write_only': True, }
|
||||
}
|
||||
|
||||
def create(self, validated_data):
|
||||
|
|
@ -113,7 +122,7 @@ class UserSerializer(serializers.ModelSerializer):
|
|||
|
||||
def validate_email(self, value):
|
||||
"""Validate email value"""
|
||||
if value == self.instance.email:
|
||||
if hasattr(self.instance, 'email') and self.instance.email and value == self.instance.email:
|
||||
raise serializers.ValidationError(detail='Equal email address.')
|
||||
return value
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from account.serializers.common import RoleBaseSerializer
|
|||
class RoleListView(generics.ListCreateAPIView):
|
||||
serializer_class = RoleBaseSerializer
|
||||
queryset = models.Role.objects.all()
|
||||
filter_class = filters.RoleListFilter
|
||||
|
||||
|
||||
class RoleTabRetrieveView(generics.GenericAPIView):
|
||||
|
|
|
|||
|
|
@ -54,6 +54,3 @@ class Image(ProjectBaseMixin, SORLImageMixin, PlatformMixin):
|
|||
if completely:
|
||||
# Delete an instance of image
|
||||
super().delete()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from timetable.models import Timetable
|
|||
from utils.legacy_parser import parse_legacy_schedule_content
|
||||
from utils.serializers import TimeZoneChoiceField
|
||||
from utils.slug_generator import generate_unique_slug
|
||||
from phonenumber_field.phonenumber import PhoneNumber
|
||||
|
||||
|
||||
class EstablishmentSerializer(serializers.ModelSerializer):
|
||||
|
|
@ -58,6 +59,7 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
|||
|
||||
def validate(self, data):
|
||||
old_type = data.pop('type', None)
|
||||
phone = data.pop('phone', None)
|
||||
|
||||
data.update({
|
||||
'slug': generate_unique_slug(Establishment, data['slug'] if data['slug'] else data['name']),
|
||||
|
|
@ -65,6 +67,7 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
|||
'establishment_type_id': self.get_type(old_type),
|
||||
'is_publish': data.get('state') == 'published',
|
||||
'subtype': self.get_subtype(old_type),
|
||||
'phone': self.get_phone(phone),
|
||||
})
|
||||
data.pop('location')
|
||||
data.pop('state')
|
||||
|
|
@ -179,6 +182,13 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
|||
establishment_type_id=establishment_type_id)
|
||||
return subtype
|
||||
|
||||
@staticmethod
|
||||
def get_phone(phone: str):
|
||||
phone_obj = PhoneNumber.from_string(phone_number=phone, region='FR')
|
||||
if phone_obj.is_valid():
|
||||
fmt = PhoneNumber.format_map[getattr(settings, 'PHONENUMBER_DB_FORMAT', 'INTERNATIONAL')]
|
||||
return phone_obj.format_as(fmt)
|
||||
|
||||
|
||||
class EstablishmentNoteSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ STATICFILES_DIRS = (
|
|||
# MEDIA
|
||||
MEDIA_LOCATION = 'media'
|
||||
|
||||
PHONENUMBER_DB_FORMAT = 'NATIONAL'
|
||||
PHONENUMBER_DB_FORMAT = 'INTERNATIONAL'
|
||||
PHONENUMBER_DEFAULT_REGION = "FR"
|
||||
|
||||
FALLBACK_LOCALE = 'en-GB'
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user