accounts: role create and list apis add

This commit is contained in:
behruz
2025-12-11 18:13:33 +05:00
parent 0177084e95
commit 1a2550be74
9 changed files with 370 additions and 2 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2 on 2025-12-11 11:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_role_user_role'),
]
operations = [
migrations.AddField(
model_name='role',
name='comment',
field=models.TextField(blank=True, null=True),
),
]

View File

@@ -7,6 +7,7 @@ from core.apps.shared.models import BaseModel
class Role(BaseModel): class Role(BaseModel):
name = models.CharField(max_length=200, unique=True, db_index=True) name = models.CharField(max_length=200, unique=True, db_index=True)
comment = models.TextField(null=True, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name

View File

@@ -0,0 +1,26 @@
# django
from django.db import transaction
# rest framework
from rest_framework import serializers
# accounts
from core.apps.accounts.models import Role
class CreateRoleSerializer(serializers.Serializer):
name = serializers.CharField()
comment = serializers.CharField(required=False)
def validate(self, data):
if Role.objects.filter(name=data['name']).exists():
raise serializers.ValidationError({"name": "Role with this name already exists"})
return data
def create(self, validated_data):
with transaction.atomic():
return Role.objects.create(
name=validated_data.get('name'),
comment=validated_data.get('comment'),
)

View File

@@ -0,0 +1,18 @@
# rest framework
from rest_framework import serializers
# accounts
from core.apps.accounts.models import Role
class ListRoleSerializer(serializers.ModelSerializer):
class Meta:
model = Role
fields = [
'id',
'name',
'comment',
'created_at',
'updated_at',
]

View File

@@ -0,0 +1,26 @@
# django
from django.db import transaction
# rest framework
from rest_framework import serializers
# accounts
from core.apps.accounts.models import Role
class UpdateRoleSerializer(serializers.Serializer):
name = serializers.CharField()
comment = serializers.CharField()
def validate(self, data):
if Role.objects.filter(name=data['name']).exists():
raise serializers.ValidationError({"name": "Role with this name already exists"})
return data
def update(self, instance, validated_data):
with transaction.atomic():
instance.name = validated_data.get('name', instance.name)
instance.comment = validated_data.get('comment', instance.comment)
instance.save()
return instance

View File

@@ -6,17 +6,21 @@ from rest_framework.routers import DefaultRouter
# accounts # accounts
# ------- user ------ # ------- user -------
from core.apps.accounts.views.user import UserViewSet from core.apps.accounts.views.user import UserViewSet
from core.apps.accounts.views.user.create import CreateUserApiView from core.apps.accounts.views.user.create import CreateUserApiView
from core.apps.accounts.views.user.list import ListUserApiView from core.apps.accounts.views.user.list import ListUserApiView
from core.apps.accounts.views.user.update import UpdateUserApiView from core.apps.accounts.views.user.update import UpdateUserApiView
from core.apps.accounts.views.user.delete import SoftDeleteUserApiView, HardDeleteUserApiView from core.apps.accounts.views.user.delete import SoftDeleteUserApiView, HardDeleteUserApiView
# ------- auth ------ # ------- auth -------
from core.apps.accounts.views.auth.login import LoginApiView from core.apps.accounts.views.auth.login import LoginApiView
# ------- role -------
from core.apps.accounts.views.role.create import CreateRoleApiView
from core.apps.accounts.views.role.list import ListRoleApiView
urlpatterns = [ urlpatterns = [
# ------ user ------
path('user/', include( path('user/', include(
[ [
path('create/', CreateUserApiView.as_view(), name='user-create-api'), path('create/', CreateUserApiView.as_view(), name='user-create-api'),
@@ -32,6 +36,13 @@ urlpatterns = [
path('login/', LoginApiView.as_view(), name='login'), path('login/', LoginApiView.as_view(), name='login'),
] ]
)), )),
# ------ role ------
path('role/', include(
[
path('create/', CreateRoleApiView.as_view(), name='create-role-api'),
path('list/', ListRoleApiView.as_view(), name='list-role-api'),
]
)),
] ]
router = DefaultRouter() router = DefaultRouter()

View File

@@ -0,0 +1,110 @@
# rest framework
from rest_framework import generics, permissions
# drf yasg
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
# accounts
from core.apps.accounts.models import Role
from core.apps.accounts.serializers.role.create import CreateRoleSerializer
from core.apps.accounts.serializers.role.list import ListRoleSerializer
# utils
from core.utils.response.mixin import ResponseMixin
class CreateRoleApiView(generics.GenericAPIView, ResponseMixin):
serializer_class = CreateRoleSerializer
queryset = Role.objects.all()
permission_classes = [permissions.IsAuthenticated]
@swagger_auto_schema(
tags=['role'],
operation_summary="Create a new role in the system",
operation_description="""
Create a new role with a name and optional comment.
Authentication:
- Requires a valid Bearer access token.
Process:
- Accepts role details in JSON format, validated using CreateRoleSerializer.
- If the data is valid, a new role is created and returned.
Request:
- Fields can include:
- name (string, required): The name of the role.
- comment (string, optional): Additional information about the role.
Response:
- 200 OK: Role successfully created and returned.
- 400 Bad Request: Validation failed, invalid input data.
- 500 Internal Server Error: Unexpected error occurred while creating the role.
Notes:
- Only authenticated users can create roles.
- The response includes the newly created role's details with timestamps.
""",
responses={
200: openapi.Response(
schema=None,
description="Success",
examples={
"application/json": {
"status_code": 200,
"status": "success",
"message": "Role successfully created",
"data": {
"id": 0,
"name": "string",
"comment": "string",
"created_at": "string",
"updated_at": "string"
}
}
}
),
400: openapi.Response(
schema=None,
description="Failure",
examples={
"application/json": {
"status_code": 400,
"status": "failure",
"message": "Kiritayotgan malumotingizni tekshirib ko'ring",
"data": "string"
}
}
),
500: openapi.Response(
schema=None,
description="Error",
examples={
"application/json": {
"status_code": 500,
"status": "error",
"message": "Xatolik, Iltimos backend dasturchiga murojaat qiling",
"data": "string"
}
}
)
}
)
def post(self, request):
try:
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
obj = serializer.save()
return self.created_response(
data=ListRoleSerializer(obj).data,
message="Role successfully created"
)
return self.failure_response(
data=serializer.errors
)
except Exception as e:
return self.error_response(
data=str(e)
)

View File

@@ -0,0 +1,106 @@
# rest framework
from rest_framework import generics, permissions
# drf yasg
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
# accounts
from core.apps.accounts.models import Role
from core.apps.accounts.serializers.role.list import ListRoleSerializer
# utils
from core.utils.response.mixin import ResponseMixin
class ListRoleApiView(generics.GenericAPIView, ResponseMixin):
serializer_class = ListRoleSerializer
queryset = Role.objects.all()
permission_classes = [permissions.IsAuthenticated]
@swagger_auto_schema(
tags=['role'],
operation_summary="Retrieve a paginated list of roles.",
operation_description="""
Get a list of all roles in the system, with optional pagination.
Authentication:
- Requires a valid Bearer access token.
Process:
- Retrieves all roles that are not marked as deleted.
- Supports pagination using the configured pagination class (limit/offset).
- Returns serialized role data along with pagination metadata.
Response:
- 200 OK: Successfully returns a paginated list of roles.
- Includes fields: count, next, previous, results.
- Each role includes id, name, comment, created_at, and updated_at.
- 500 Internal Server Error: Unexpected error occurred while fetching roles.
Notes:
- Only authenticated users can access this endpoint.
- Roles marked as deleted (`is_deleted=True`) are excluded from the response.
- Pagination fields (`next` and `previous`) provide URLs to navigate pages if results exceed page limit.
""",
responses={
200: openapi.Response(
description="Succes",
schema=None,
examples={
"application/json": {
"status_code": 200,
"status": "success",
"message": "Roles list",
"data": {
"count": 0,
"next": "string",
"previous": "string",
"results": [
{
"id": 1,
"name": "string",
"comment": "string",
"created_at": "string",
"updated_at": "string"
},
]
}
}
}
),
500: openapi.Response(
description="Error",
schema=None,
examples={
"application/json": {
"status_code": 500,
"status": "error",
"message": "Xatolik, Iltimos backend dasturchiga murojaat qiling",
"data": "string"
}
}
),
}
)
def get(self, request):
try:
queryset = self.queryset.filter(is_deleted=False)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.serializer_class(page, many=True)
return self.success_response(
data=self.get_paginated_response(serializer.data).data,
message="Roles list"
)
serializer = self.serializer_class(queryset, many=True)
return self.success_response(
data=serializer.data,
message="Roles list"
)
except Exception as e:
return self.error_response(
data=str(e)
)

View File

@@ -0,0 +1,52 @@
# rest framework
from rest_framework import generics, permissions
# drf yasg
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
# accounts
from core.apps.accounts.models import Role
from core.apps.accounts.serializers.role.update import UpdateRoleSerializer
from core.apps.accounts.serializers.role.list import ListRoleSerializer
# utils
from core.utils.response.mixin import ResponseMixin
class UpdateRoleApiView(generics.GenericAPIView, ResponseMixin):
serializer_class = UpdateRoleSerializer
queryset = Role.objects.filter(is_deleted=False)
permission_classes = [permissions.IsAuthenticated]
@swagger_auto_schema(
tags=['role'],
operation_summary="",
operation_description="""
""",
responses={}
)
def patch(self, request, id):
try:
instance = Role.objects.filter(id=id).first()
if not instance:
return self.not_found_response(data={}, message="Role not found with this id")
serializer = self.serializer_class(data=request.data, instance=instance, partial=True)
if serializer.is_valid():
updated_instance = serializer.save()
return self.success_response(
data=ListRoleSerializer(updated_instance).data,
message="Role successfully updated"
)
return self.failure_response(
data=serializer.errors,
)
except Exception as e:
return self.error_response(
data=str(e)
)