Implement exchange imports and frontend reporting APIs
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 3m50s
CI/CD Pipeline / Run Tests (push) Successful in 3m57s
CI/CD Pipeline / Build Docker Images (push) Has been skipped
CI/CD Pipeline / Push to Gitea Registry (push) Has been skipped
CI/CD Pipeline / Deploy to Server (push) Has been skipped
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 3m50s
CI/CD Pipeline / Run Tests (push) Successful in 3m57s
CI/CD Pipeline / Build Docker Images (push) Has been skipped
CI/CD Pipeline / Push to Gitea Registry (push) Has been skipped
CI/CD Pipeline / Deploy to Server (push) Has been skipped
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""Admin configuration for user app."""
|
||||
|
||||
from apps.core.models import BackgroundJob
|
||||
from apps.user.models import Profile, User
|
||||
from contextlib import suppress
|
||||
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin.sites import NotRegistered
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
@@ -9,6 +9,9 @@ from django.contrib.auth.models import Group
|
||||
from django.utils.html import format_html
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.core.models import BackgroundJob
|
||||
from apps.user.models import Profile, User
|
||||
|
||||
try:
|
||||
from django_celery_beat.models import (
|
||||
ClockedSchedule,
|
||||
@@ -38,10 +41,8 @@ def _unregister(model) -> None:
|
||||
if model is None:
|
||||
return
|
||||
|
||||
try:
|
||||
with suppress(NotRegistered):
|
||||
admin.site.unregister(model)
|
||||
except NotRegistered:
|
||||
pass
|
||||
|
||||
|
||||
_unregister(User)
|
||||
|
||||
@@ -86,6 +86,73 @@ class UserSerializer(serializers.ModelSerializer):
|
||||
read_only_fields = ("id", "is_verified", "created_at", "updated_at")
|
||||
|
||||
|
||||
class CurrentUserProfileSerializer(serializers.ModelSerializer):
|
||||
"""Профиль текущего пользователя в контракте `/users/me/`."""
|
||||
|
||||
middle_name = serializers.CharField(source="mid_name", allow_null=True)
|
||||
full_name = serializers.ReadOnlyField()
|
||||
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = (
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"full_name",
|
||||
)
|
||||
|
||||
|
||||
class CurrentUserCapabilitiesSerializer(serializers.Serializer):
|
||||
"""Возможности пользователя для UI-контрактов."""
|
||||
|
||||
can_access_admin_page = serializers.BooleanField()
|
||||
|
||||
|
||||
class CurrentUserSerializer(serializers.ModelSerializer):
|
||||
"""Расширенный сериализатор текущего пользователя."""
|
||||
|
||||
profile = CurrentUserProfileSerializer(read_only=True)
|
||||
role = serializers.SerializerMethodField()
|
||||
role_label = serializers.SerializerMethodField()
|
||||
capabilities = serializers.SerializerMethodField()
|
||||
|
||||
@staticmethod
|
||||
def get_role(obj) -> str:
|
||||
if obj.is_superuser:
|
||||
return "admin"
|
||||
if obj.is_staff:
|
||||
return "staff"
|
||||
return "user"
|
||||
|
||||
def get_role_label(self, obj) -> str:
|
||||
labels = {
|
||||
"admin": "Администратор системы",
|
||||
"staff": "Сотрудник системы",
|
||||
"user": "Пользователь системы",
|
||||
}
|
||||
return labels[self.get_role(obj)]
|
||||
|
||||
@staticmethod
|
||||
def get_capabilities(obj) -> dict[str, bool]:
|
||||
return {
|
||||
"can_access_admin_page": bool(obj.is_staff or obj.is_superuser),
|
||||
}
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = (
|
||||
"id",
|
||||
"username",
|
||||
"email",
|
||||
"phone",
|
||||
"is_active",
|
||||
"role",
|
||||
"role_label",
|
||||
"capabilities",
|
||||
"profile",
|
||||
)
|
||||
|
||||
|
||||
class UserUpdateSerializer(serializers.ModelSerializer):
|
||||
"""Сериализатор для обновления данных пользователя"""
|
||||
|
||||
@@ -99,7 +166,14 @@ class ProfileUpdateSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = ("first_name", "mid_name", "last_name", "bio", "avatar", "date_of_birth")
|
||||
fields = (
|
||||
"first_name",
|
||||
"mid_name",
|
||||
"last_name",
|
||||
"bio",
|
||||
"avatar",
|
||||
"date_of_birth",
|
||||
)
|
||||
|
||||
|
||||
class LoginSerializer(serializers.Serializer):
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from typing import Any
|
||||
|
||||
from apps.core.exceptions import NotFoundError
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import transaction
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
|
||||
from apps.core.exceptions import NotFoundError
|
||||
|
||||
from .models import Profile
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
@@ -10,6 +10,7 @@ from rest_framework.views import APIView
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
|
||||
from .serializers import (
|
||||
CurrentUserSerializer,
|
||||
LoginSerializer,
|
||||
PasswordChangeSerializer,
|
||||
ProfileUpdateSerializer,
|
||||
@@ -125,10 +126,10 @@ class CurrentUserView(APIView):
|
||||
tags=[USER_TAG],
|
||||
operation_summary="Текущий пользователь",
|
||||
operation_description="Возвращает данные авторизованного пользователя.",
|
||||
responses={200: UserSerializer},
|
||||
responses={200: CurrentUserSerializer},
|
||||
)
|
||||
def get(self, request):
|
||||
serializer = UserSerializer(request.user)
|
||||
serializer = CurrentUserSerializer(request.user)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user