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

This commit is contained in:
2026-04-07 16:31:04 +02:00
parent 76a86d0b20
commit 697ecb7d1c
155 changed files with 5604 additions and 346 deletions

View File

@@ -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)

View File

@@ -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):

View File

@@ -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()

View File

@@ -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)