accounts: role create and list apis add
This commit is contained in:
18
core/apps/accounts/migrations/0003_role_comment.py
Normal file
18
core/apps/accounts/migrations/0003_role_comment.py
Normal 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),
|
||||
),
|
||||
]
|
||||
@@ -7,6 +7,7 @@ from core.apps.shared.models import BaseModel
|
||||
|
||||
class Role(BaseModel):
|
||||
name = models.CharField(max_length=200, unique=True, db_index=True)
|
||||
comment = models.TextField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
26
core/apps/accounts/serializers/role/create.py
Normal file
26
core/apps/accounts/serializers/role/create.py
Normal 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'),
|
||||
)
|
||||
18
core/apps/accounts/serializers/role/list.py
Normal file
18
core/apps/accounts/serializers/role/list.py
Normal 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',
|
||||
]
|
||||
26
core/apps/accounts/serializers/role/update.py
Normal file
26
core/apps/accounts/serializers/role/update.py
Normal 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
|
||||
@@ -6,17 +6,21 @@ from rest_framework.routers import DefaultRouter
|
||||
|
||||
|
||||
# accounts
|
||||
# ------- user ------
|
||||
# ------- user -------
|
||||
from core.apps.accounts.views.user import UserViewSet
|
||||
from core.apps.accounts.views.user.create import CreateUserApiView
|
||||
from core.apps.accounts.views.user.list import ListUserApiView
|
||||
from core.apps.accounts.views.user.update import UpdateUserApiView
|
||||
from core.apps.accounts.views.user.delete import SoftDeleteUserApiView, HardDeleteUserApiView
|
||||
# ------- auth ------
|
||||
# ------- auth -------
|
||||
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 = [
|
||||
# ------ user ------
|
||||
path('user/', include(
|
||||
[
|
||||
path('create/', CreateUserApiView.as_view(), name='user-create-api'),
|
||||
@@ -32,6 +36,13 @@ urlpatterns = [
|
||||
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()
|
||||
|
||||
110
core/apps/accounts/views/role/create.py
Normal file
110
core/apps/accounts/views/role/create.py
Normal 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)
|
||||
)
|
||||
106
core/apps/accounts/views/role/list.py
Normal file
106
core/apps/accounts/views/role/list.py
Normal 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)
|
||||
)
|
||||
52
core/apps/accounts/views/role/update.py
Normal file
52
core/apps/accounts/views/role/update.py
Normal 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)
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user