Реализовал систему разрешений
This commit is contained in:
@@ -32,12 +32,14 @@ from .models import (
|
||||
Geo,
|
||||
ObjItem,
|
||||
CustomUser,
|
||||
UserPermission,
|
||||
Band,
|
||||
Source,
|
||||
TechAnalyze,
|
||||
SourceRequest,
|
||||
SourceRequestStatusHistory,
|
||||
)
|
||||
from .permissions import PERMISSIONS, DEFAULT_ROLE_PERMISSIONS
|
||||
from .filters import (
|
||||
GeoKupDistanceFilter,
|
||||
GeoValidDistanceFilter,
|
||||
@@ -99,6 +101,19 @@ class CustomUserInline(admin.StackedInline):
|
||||
model = CustomUser
|
||||
can_delete = False
|
||||
verbose_name_plural = "Дополнительная информация пользователя"
|
||||
filter_horizontal = ('user_permissions',)
|
||||
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': ('role',)
|
||||
}),
|
||||
('Индивидуальные разрешения', {
|
||||
'fields': ('use_custom_permissions', 'user_permissions'),
|
||||
'classes': ('collapse',),
|
||||
'description': 'Если включено "Использовать индивидуальные разрешения", '
|
||||
'будут использоваться выбранные разрешения вместо прав роли по умолчанию.'
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class LocationForm(forms.ModelForm):
|
||||
@@ -195,6 +210,88 @@ class UserAdmin(BaseUserAdmin):
|
||||
admin.site.register(User, UserAdmin)
|
||||
|
||||
|
||||
class UserPermissionForm(forms.ModelForm):
|
||||
"""Форма для UserPermission с выбором из списка разрешений."""
|
||||
|
||||
code = forms.ChoiceField(
|
||||
choices=[],
|
||||
label="Код разрешения",
|
||||
help_text="Выберите разрешение из списка"
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['code'].choices = PERMISSIONS[:28] # Используем PERMISSION_CHOICES
|
||||
# Преобразуем в формат (code, name)
|
||||
self.fields['code'].choices = [(code, name) for code, name, _ in PERMISSIONS]
|
||||
|
||||
class Meta:
|
||||
model = UserPermission
|
||||
fields = ['code']
|
||||
|
||||
|
||||
@admin.register(UserPermission)
|
||||
class UserPermissionAdmin(BaseAdmin):
|
||||
"""Админ-панель для модели UserPermission."""
|
||||
|
||||
form = UserPermissionForm
|
||||
list_display = ('code', 'get_name', 'get_description')
|
||||
search_fields = ('code',)
|
||||
ordering = ('code',)
|
||||
|
||||
def get_name(self, obj):
|
||||
"""Возвращает название разрешения."""
|
||||
from .permissions import PERMISSION_CHOICES
|
||||
choices_dict = dict(PERMISSION_CHOICES)
|
||||
return choices_dict.get(obj.code, '-')
|
||||
get_name.short_description = 'Название'
|
||||
|
||||
def get_description(self, obj):
|
||||
"""Возвращает описание разрешения."""
|
||||
from .permissions import PERMISSION_DESCRIPTIONS
|
||||
return PERMISSION_DESCRIPTIONS.get(obj.code, '-')
|
||||
get_description.short_description = 'Описание'
|
||||
|
||||
|
||||
@admin.register(CustomUser)
|
||||
class CustomUserAdmin(BaseAdmin):
|
||||
"""Админ-панель для модели CustomUser с управлением разрешениями."""
|
||||
|
||||
list_display = ('user', 'role', 'use_custom_permissions', 'permissions_count')
|
||||
list_filter = ('role', 'use_custom_permissions')
|
||||
search_fields = ('user__username', 'user__first_name', 'user__last_name')
|
||||
filter_horizontal = ('user_permissions',)
|
||||
ordering = ('user__username',)
|
||||
|
||||
fieldsets = (
|
||||
('Основная информация', {
|
||||
'fields': ('user', 'role')
|
||||
}),
|
||||
('Индивидуальные разрешения', {
|
||||
'fields': ('use_custom_permissions', 'user_permissions'),
|
||||
'description': 'Если включено "Использовать индивидуальные разрешения", '
|
||||
'будут использоваться выбранные разрешения вместо прав роли по умолчанию.'
|
||||
}),
|
||||
)
|
||||
|
||||
def permissions_count(self, obj):
|
||||
"""Показывает количество индивидуальных разрешений."""
|
||||
if obj.use_custom_permissions:
|
||||
count = obj.user_permissions.count()
|
||||
return f'{count} (индивид.)'
|
||||
return f'По роли ({obj.role})'
|
||||
permissions_count.short_description = 'Разрешения'
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
"""User поле только для чтения при редактировании."""
|
||||
if obj:
|
||||
return ('user',)
|
||||
return ()
|
||||
|
||||
class Media:
|
||||
js = ('admin/js/permissions_admin.js',)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Custom Admin Actions
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user