refactored roles, refactored response for User detail view

This commit is contained in:
Anatoly 2020-01-14 18:40:30 +03:00
parent 1ed384ded2
commit 5c95c4923f
12 changed files with 225 additions and 41 deletions

View File

@ -8,11 +8,13 @@ from account import models
@admin.register(models.Role)
class RoleAdmin(admin.ModelAdmin):
list_display = ['role', 'country']
raw_id_fields = ['country', ]
@admin.register(models.UserRole)
class UserRoleAdmin(admin.ModelAdmin):
list_display = ['user', 'role', 'establishment']
list_display = ['user', 'role', 'establishment', ]
raw_id_fields = ['user', 'role', 'establishment', 'requester', ]
@admin.register(models.User)

View File

@ -0,0 +1,26 @@
# Generated by Django 2.2.7 on 2020-01-14 13:11
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('main', '0046_auto_20200114_1218'),
('account', '0031_user_last_country'),
]
operations = [
migrations.AddField(
model_name='role',
name='navigation_bar_permission',
field=models.ForeignKey(blank=True, help_text='navigation bar item permission', null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.NavigationBarPermission', verbose_name='navigation bar permission'),
),
migrations.AlterField(
model_name='userrole',
name='requester',
field=models.ForeignKey(blank=True, default=None, help_text='A user (REQUESTER) who requests a role change for a USER', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='roles_requested', to=settings.AUTH_USER_MODEL),
),
]

View File

@ -53,6 +53,7 @@ class Role(ProjectBaseMixin):
(LIQUOR_REVIEWER, 'Liquor reviewer'),
(PRODUCT_REVIEWER, 'Product reviewer'),
)
role = models.PositiveIntegerField(verbose_name=_('Role'), choices=ROLE_CHOICES,
null=False, blank=False)
country = models.ForeignKey(Country, verbose_name=_('Country'),
@ -62,6 +63,11 @@ class Role(ProjectBaseMixin):
establishment_subtype = models.ForeignKey(EstablishmentSubType,
verbose_name=_('Establishment subtype'),
null=True, blank=True, on_delete=models.SET_NULL)
navigation_bar_permission = models.ForeignKey('main.NavigationBarPermission',
blank=True, null=True,
on_delete=models.SET_NULL,
help_text='navigation bar item permission',
verbose_name=_('navigation bar permission'))
class UserManager(BaseUserManager):
@ -348,6 +354,7 @@ class UserRole(ProjectBaseMixin):
(CANCELLED, _('cancelled')),
(REJECTED, _('rejected'))
)
user = models.ForeignKey(
'account.User', verbose_name=_('User'), on_delete=models.CASCADE)
role = models.ForeignKey(
@ -358,9 +365,11 @@ class UserRole(ProjectBaseMixin):
state = models.CharField(
_('state'), choices=STATE_CHOICES, max_length=10, default=PENDING)
requester = models.ForeignKey(
'account.User', blank=True, null=True, default=None, related_name='roles_requested',
on_delete=models.SET_NULL)
requester = models.ForeignKey('account.User', on_delete=models.SET_NULL,
blank=True, null=True, default=None,
related_name='roles_requested',
help_text='A user (REQUESTER) who requests a '
'role change for a USER')
class Meta:
unique_together = ['user', 'role', 'establishment', 'state']

View File

@ -0,0 +1,3 @@
from account.serializers.common import *
from account.serializers.web import *
from account.serializers.back import *

View File

@ -3,15 +3,7 @@ from rest_framework import serializers
from account import models
from account.models import User
from main.models import SiteSettings
class RoleSerializer(serializers.ModelSerializer):
class Meta:
model = models.Role
fields = [
'role',
'country'
]
# from account.serializers.common import RoleBaseSerializer
class _SiteSettingsSerializer(serializers.ModelSerializer):
@ -26,6 +18,7 @@ class _SiteSettingsSerializer(serializers.ModelSerializer):
class BackUserSerializer(serializers.ModelSerializer):
last_country = _SiteSettingsSerializer(read_only=True)
# roles = RoleBaseSerializer(many=True, read_only=True)
class Meta:
model = User
@ -45,12 +38,12 @@ class BackUserSerializer(serializers.ModelSerializer):
'unconfirmed_email',
'email_confirmed',
'newsletter',
'roles',
'password',
'city',
'locale',
'last_ip',
'last_country',
# 'roles',
)
extra_kwargs = {
'password': {'write_only': True},

View File

@ -1,7 +1,7 @@
"""Common account serializers"""
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.contrib.auth import password_validation as password_validators
from django.utils.translation import gettext_lazy as _
from fcm_django.models import FCMDevice
from rest_framework import exceptions
from rest_framework import serializers
@ -11,9 +11,25 @@ from account import models, tasks
from notification.models import Subscriber
from utils import exceptions as utils_exceptions
from utils import methods as utils_methods
from main.serializers import NavigationBarPermissionBaseSerializer
# User serializers
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)
class Meta:
"""Meta class."""
model = models.Role
fields = [
'id',
'role_display',
'navigation_bar_permission',
]
class UserSerializer(serializers.ModelSerializer):
"""User serializer."""
# RESPONSE
@ -26,6 +42,7 @@ class UserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(
validators=(rest_validators.UniqueValidator(queryset=models.User.objects.all()),),
required=False)
roles = RoleBaseSerializer(many=True, read_only=True)
class Meta:
model = models.User
@ -39,6 +56,7 @@ class UserSerializer(serializers.ModelSerializer):
'email',
'email_confirmed',
'newsletter',
'roles',
]
extra_kwargs = {
'first_name': {'required': False, 'write_only': True, },

View File

@ -6,9 +6,9 @@ from account.views import back as views
app_name = 'account'
urlpatterns = [
path('role/', views.RoleLstView.as_view(), name='role-list-create'),
path('user-role/', views.UserRoleLstView.as_view(), name='user-role-list-create'),
path('user/', views.UserLstView.as_view(), name='user-create-list'),
path('role/', views.RoleListView.as_view(), name='role-list-create'),
path('user-role/', views.UserRoleListView.as_view(), name='user-role-list-create'),
path('user/', views.UserListView.as_view(), name='user-create-list'),
path('user/<int:id>/', views.UserRUDView.as_view(), name='user-rud'),
path('user/<int:id>/csv/', views.get_user_csv, name='user-csv'),
]

View File

@ -8,19 +8,20 @@ from rest_framework.authtoken.models import Token
from account import models
from account.models import User
from account.serializers import back as serializers
from account.serializers.common import RoleBaseSerializer
class RoleLstView(generics.ListCreateAPIView):
serializer_class = serializers.RoleSerializer
class RoleListView(generics.ListCreateAPIView):
serializer_class = RoleBaseSerializer
queryset = models.Role.objects.all()
class UserRoleLstView(generics.ListCreateAPIView):
class UserRoleListView(generics.ListCreateAPIView):
serializer_class = serializers.UserRoleSerializer
queryset = models.UserRole.objects.all()
class UserLstView(generics.ListCreateAPIView):
class UserListView(generics.ListCreateAPIView):
"""User list create view."""
queryset = User.objects.prefetch_related('roles')
serializer_class = serializers.BackUserSerializer

View File

@ -14,6 +14,14 @@ class SiteSettingsAdmin(admin.ModelAdmin):
inlines = [SiteSettingsInline, ]
@admin.register(models.SiteFeature)
class SiteFeatureAdmin(admin.ModelAdmin):
"""Site feature admin conf."""
list_display = ['id', 'site_settings', 'feature',
'published', 'main', 'backoffice', ]
raw_id_fields = ['site_settings', 'feature', ]
@admin.register(models.Feature)
class FeatureAdmin(admin.ModelAdmin):
"""Feature admin conf."""
@ -80,3 +88,14 @@ class PanelAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'user', 'created',)
raw_id_fields = ('user',)
list_display_links = ('id', 'name',)
@admin.register(models.NavigationBarPermission)
class NavigationBarPermissionAdmin(admin.ModelAdmin):
"""NavigationBarPermission admin."""
list_display = ('section', 'permission_mode_display', )
raw_id_fields = ('section', )
def permission_mode_display(self, obj):
"""Get permission mode display."""
return obj.get_permission_mode_display()

View File

@ -0,0 +1,44 @@
# Generated by Django 2.2.7 on 2020-01-14 12:18
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('main', '0045_carousel_is_international'),
]
operations = [
migrations.AddField(
model_name='sitefeature',
name='backoffice',
field=models.BooleanField(default=False, help_text='shows on backoffice page', verbose_name='backoffice'),
),
migrations.AlterField(
model_name='sitefeature',
name='main',
field=models.BooleanField(default=False, help_text='shows on main page', verbose_name='Main'),
),
migrations.AlterField(
model_name='sitefeature',
name='nested',
field=models.ManyToManyField(to='main.SiteFeature', blank=True),
),
migrations.CreateModel(
name='NavigationBarPermission',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('permission_mode', models.PositiveSmallIntegerField(choices=[(0, 'read'), (1, 'write')], default=0, help_text='READ - allows only retrieve data,WRITE - allows to perform any operations over the object', verbose_name='permission mode')),
('section', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.SiteFeature', verbose_name='section')),
],
options={
'verbose_name': 'Navigation bar item permission',
'verbose_name_plural': 'Navigation bar item permissions',
},
),
]

View File

@ -6,10 +6,11 @@ from django.contrib.contenttypes import fields as generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import JSONField
from django.core.validators import EMPTY_VALUES
from django.db import connections, connection
from django.db import connections
from django.db import models
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey
from rest_framework import exceptions
from configuration.models import TranslationSettings
@ -144,9 +145,15 @@ class SiteFeature(ProjectBaseMixin):
site_settings = models.ForeignKey(SiteSettings, on_delete=models.CASCADE)
feature = models.ForeignKey(Feature, on_delete=models.PROTECT)
published = models.BooleanField(default=False, verbose_name=_('Published'))
main = models.BooleanField(default=False, verbose_name=_('Main'))
nested = models.ManyToManyField('self', symmetrical=False)
main = models.BooleanField(default=False,
help_text='shows on main page',
verbose_name=_('Main'),)
backoffice = models.BooleanField(default=False,
help_text='shows on backoffice page',
verbose_name=_('backoffice'),)
nested = models.ManyToManyField('self', blank=True, symmetrical=False)
old_id = models.IntegerField(null=True, blank=True)
objects = SiteFeatureQuerySet.as_manager()
@ -520,3 +527,29 @@ class Panel(ProjectBaseMixin):
params = params + new_params
query = self.query + limit_offset
return query, params
class NavigationBarPermission(ProjectBaseMixin):
"""Model for navigation bar item permissions."""
READ = 0
WRITE = 1
PERMISSION_MODES = (
(READ, _('read')),
(WRITE, _('write')),
)
section = models.ForeignKey('main.SiteFeature',
on_delete=models.CASCADE,
verbose_name=_('section'))
permission_mode = models.PositiveSmallIntegerField(choices=PERMISSION_MODES,
default=READ,
help_text='READ - allows only retrieve data,'
'WRITE - allows to perform any '
'operations over the object',
verbose_name=_('permission mode'))
class Meta:
"""Meta class."""
verbose_name = _('Navigation bar item permission')
verbose_name_plural = _('Navigation bar item permissions')

View File

@ -2,11 +2,11 @@
from django.contrib.contenttypes.models import ContentType
from rest_framework import serializers
from account.models import User
from account.serializers.back import BackUserSerializer
from location.serializers import CountrySerializer
from main import models
from utils.serializers import ProjectModelSerializer, TranslatedField, RecursiveFieldSerializer
from account.serializers.back import BackUserSerializer
from account.models import User
class FeatureSerializer(serializers.ModelSerializer):
@ -84,24 +84,43 @@ class FooterBackSerializer(FooterSerializer):
class SiteFeatureSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(source='feature.id')
slug = serializers.CharField(source='feature.slug')
priority = serializers.IntegerField(source='feature.priority')
route = serializers.CharField(source='feature.route.name')
source = serializers.IntegerField(source='feature.source')
nested = RecursiveFieldSerializer(many=True, allow_null=True)
id = serializers.IntegerField(source='feature.id', allow_null=True)
slug = serializers.CharField(source='feature.slug', allow_null=True)
priority = serializers.IntegerField(source='feature.priority', allow_null=True)
route = serializers.CharField(source='feature.route.name', allow_null=True)
source = serializers.IntegerField(source='feature.source', allow_null=True)
nested = RecursiveFieldSerializer(many=True, read_only=True, allow_null=True)
class Meta:
"""Meta class."""
model = models.SiteFeature
fields = ('main',
'id',
'slug',
'priority',
'route',
'source',
'nested',
)
fields = (
'id',
'main',
'slug',
'priority',
'route',
'source',
'nested',
)
class NavigationBarSectionBaseSerializer(SiteFeatureSerializer):
"""Serializer for navigation bar."""
source_display = serializers.CharField(source='feature.get_source_display',
read_only=True)
class Meta(SiteFeatureSerializer.Meta):
model = models.SiteFeature
fields = [
'id',
'slug',
'route',
'source',
'source_display',
'priority',
'nested',
]
class SiteSettingsSerializer(serializers.ModelSerializer):
@ -331,3 +350,20 @@ class PanelExecuteSerializer(serializers.ModelSerializer):
'user',
'user_id'
]
class NavigationBarPermissionBaseSerializer(serializers.ModelSerializer):
"""Navigation bar permission serializer."""
section = NavigationBarSectionBaseSerializer(read_only=True)
permission_mode_display = serializers.CharField(source='get_permission_mode_display',
read_only=True)
class Meta:
"""Meta class."""
model = models.NavigationBarPermission
fields = [
'id',
'section',
'permission_mode_display',
]