shared_account app olib tashlandi
This commit is contained in:
@@ -14,3 +14,5 @@ docker exec -it <container_name> bash
|
|||||||
|
|
||||||
python manage.py createclient
|
python manage.py createclient
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ SHARED_APPS = [
|
|||||||
'django_tenants',
|
'django_tenants',
|
||||||
'core.apps.customers',
|
'core.apps.customers',
|
||||||
# django apps
|
# django apps
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
TENANT_APPS = [
|
||||||
|
# django apps
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
@@ -25,11 +30,6 @@ SHARED_APPS = [
|
|||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
# local apps
|
# local apps
|
||||||
'core.apps.shared_accounts',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
TENANT_APPS = [
|
|
||||||
'core.apps.accounts',
|
'core.apps.accounts',
|
||||||
'core.apps.shared',
|
'core.apps.shared',
|
||||||
'core.apps.products',
|
'core.apps.products',
|
||||||
@@ -123,7 +123,7 @@ MEDIA_ROOT = BASE_DIR / 'resources/media'
|
|||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
AUTH_USER_MODEL = 'shared_accounts.AdminUser'
|
AUTH_USER_MODEL = 'accounts.User'
|
||||||
|
|
||||||
# Django tenants
|
# Django tenants
|
||||||
TENANT_MODEL = "customers.Client"
|
TENANT_MODEL = "customers.Client"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.2 on 2025-12-07 09:47
|
# Generated by Django 5.2 on 2025-12-07 13:08
|
||||||
|
|
||||||
import django.contrib.auth.models
|
import django.contrib.auth.models
|
||||||
import django.contrib.auth.validators
|
import django.contrib.auth.validators
|
||||||
@@ -12,6 +12,7 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
('auth', '0012_alter_user_first_name_max_length'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
@@ -31,8 +32,11 @@ class Migration(migrations.Migration):
|
|||||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
('updated_at', models.DateTimeField(auto_now=True)),
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('is_deleted', models.BooleanField(default=False)),
|
||||||
('profile_image', models.ImageField(blank=True, null=True, upload_to='user/profile_images/')),
|
('profile_image', models.ImageField(blank=True, null=True, upload_to='user/profile_images/')),
|
||||||
('phone_number', models.CharField(blank=True, max_length=15, null=True, validators=[django.core.validators.RegexValidator(message='The phone_number is invalid. The format should be like this: +998XXXXXXXXX', regex='^\\+998\\d{9}$')])),
|
('phone_number', models.CharField(blank=True, max_length=15, null=True, validators=[django.core.validators.RegexValidator(message='The phone_number is invalid. The format should be like this: +998XXXXXXXXX', regex='^\\+998\\d{9}$')])),
|
||||||
|
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
||||||
|
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'user',
|
'verbose_name': 'user',
|
||||||
|
|||||||
@@ -21,13 +21,10 @@ class User(AbstractUser, BaseModel):
|
|||||||
phone_number = models.CharField(
|
phone_number = models.CharField(
|
||||||
max_length=15, null=True, blank=True, validators=[uz_phone_validator]
|
max_length=15, null=True, blank=True, validators=[uz_phone_validator]
|
||||||
)
|
)
|
||||||
groups = None
|
|
||||||
user_permissions = None
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"#{self.id}: {self.first_name} {self.last_name}"
|
return f"#{self.id}: {self.first_name} {self.last_name}"
|
||||||
|
|
||||||
@property
|
|
||||||
def get_jwt_token(self):
|
def get_jwt_token(self):
|
||||||
token = RefreshToken.for_user(self)
|
token = RefreshToken.for_user(self)
|
||||||
return {
|
return {
|
||||||
|
|||||||
18
core/apps/accounts/serializers/auth/login.py
Normal file
18
core/apps/accounts/serializers/auth/login.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# rest framework
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class LoginSerializer(serializers.Serializer):
|
||||||
|
username = serializers.CharField()
|
||||||
|
password = serializers.CharField()
|
||||||
|
|
||||||
|
def validate(self, data):
|
||||||
|
user = User.objects.filter(username=data['username']).first()
|
||||||
|
if not user or (user and not user.check_password(data['password'])):
|
||||||
|
raise serializers.ValidationError({"user": "Username yoki parol noto'g'ri"})
|
||||||
|
data['user'] = user
|
||||||
|
return data
|
||||||
22
core/apps/accounts/serializers/user/user.py
Normal file
22
core/apps/accounts/serializers/user/user.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# rest framework
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'first_name',
|
||||||
|
'last_name',
|
||||||
|
'username',
|
||||||
|
'phone_number',
|
||||||
|
'profile_image',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
]
|
||||||
|
|
||||||
@@ -1,8 +1,15 @@
|
|||||||
# django
|
# django
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
||||||
# rest framework simplejwt
|
# rest framework
|
||||||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
# ------- user ------
|
||||||
|
from core.apps.accounts.views.user import UserViewSet
|
||||||
|
# ------- auth ------
|
||||||
|
from core.apps.accounts.views.auth.login import LoginApiView
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -14,8 +21,13 @@ urlpatterns = [
|
|||||||
# ------ authentication ------
|
# ------ authentication ------
|
||||||
path('auth/', include(
|
path('auth/', include(
|
||||||
[
|
[
|
||||||
path('login/', TokenObtainPairView.as_view(), name='login-api'),
|
path('login/', LoginApiView.as_view(), name='login'),
|
||||||
path('token/refresh/', TokenRefreshView.as_view(), name='token-refresh-api'),
|
|
||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register("user", UserViewSet)
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns += router.urls
|
||||||
|
|||||||
75
core/apps/accounts/views/auth/login.py
Normal file
75
core/apps/accounts/views/auth/login.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# rest framework
|
||||||
|
from rest_framework import generics
|
||||||
|
|
||||||
|
# drf yasg
|
||||||
|
from drf_yasg import openapi
|
||||||
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
|
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
from core.apps.accounts.serializers.auth import login as serializers
|
||||||
|
from core.apps.accounts.serializers.user import UserSerializer
|
||||||
|
|
||||||
|
# utils
|
||||||
|
from core.utils.response.mixin import ResponseMixin
|
||||||
|
|
||||||
|
|
||||||
|
class LoginApiView(generics.GenericAPIView, ResponseMixin):
|
||||||
|
serializer_class = serializers.LoginSerializer
|
||||||
|
queryset = User.objects.all()
|
||||||
|
|
||||||
|
@swagger_auto_schema(
|
||||||
|
tags=["Authentication and Authorization"],
|
||||||
|
responses={
|
||||||
|
200: openapi.Response(
|
||||||
|
description="Success",
|
||||||
|
schema=None,
|
||||||
|
examples={
|
||||||
|
"application/json": {
|
||||||
|
"status_code": 200,
|
||||||
|
"status": "success",
|
||||||
|
"message": "Login muvaffaqiyatli amalga oshirildi",
|
||||||
|
"data": {
|
||||||
|
"user": {
|
||||||
|
"id": 0,
|
||||||
|
"first_name": "string",
|
||||||
|
"last_name": "string",
|
||||||
|
"username": "string",
|
||||||
|
"phone_number": "string",
|
||||||
|
"profile_image": "string",
|
||||||
|
"created_at": "string",
|
||||||
|
"updated_at": "string",
|
||||||
|
},
|
||||||
|
"tokens": {
|
||||||
|
"access_token": "string",
|
||||||
|
"refresh_token": "string",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def post(self, request):
|
||||||
|
try:
|
||||||
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
user = serializer.validated_data.get('user')
|
||||||
|
token = user.get_jwt_token()
|
||||||
|
data = {
|
||||||
|
"user": UserSerializer(user).data,
|
||||||
|
"tokens": token,
|
||||||
|
}
|
||||||
|
return self.success_response(
|
||||||
|
data=data,
|
||||||
|
message="Login muvaffaqiyatli amalga oshirildi"
|
||||||
|
)
|
||||||
|
return self.failure_response(
|
||||||
|
data=serializer.errors,
|
||||||
|
message="Kiritayotgan malumotingizni tekshirib ko'ring"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return self.error_response(
|
||||||
|
data=str(e)
|
||||||
|
)
|
||||||
45
core/apps/accounts/views/user/user.py
Normal file
45
core/apps/accounts/views/user/user.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# rest framework
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
|
||||||
|
# drf yasg
|
||||||
|
from drf_yasg import openapi
|
||||||
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
|
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
from core.apps.accounts.serializers.user import user as serializers
|
||||||
|
|
||||||
|
# utils
|
||||||
|
from core.utils.response.mixin import ResponseMixin
|
||||||
|
from core.utils.permissions.tenant_user import IsTenantUser
|
||||||
|
|
||||||
|
|
||||||
|
class UserViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||||
|
queryset = User.objects.all()
|
||||||
|
permission_classes = [IsTenantUser]
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
match self.action:
|
||||||
|
case "POST":
|
||||||
|
return
|
||||||
|
case ["PUT", "PATCH"]:
|
||||||
|
return
|
||||||
|
case _:
|
||||||
|
return serializers.UserSerializer
|
||||||
|
|
||||||
|
@action(
|
||||||
|
methods=["GET"], url_name="me", url_path="me", detail=False
|
||||||
|
)
|
||||||
|
def me(self, request):
|
||||||
|
try:
|
||||||
|
serializer = self.get_serializer(request.user)
|
||||||
|
return self.success_response(
|
||||||
|
data=serializer.data,
|
||||||
|
message="User ma'lumotlari"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return self.error_response(
|
||||||
|
data=str(e),
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.2 on 2025-12-07 09:47
|
# Generated by Django 5.2 on 2025-12-07 13:08
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import django_tenants.postgresql_backend.base
|
import django_tenants.postgresql_backend.base
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.2 on 2025-12-07 09:47
|
# Generated by Django 5.2 on 2025-12-07 13:08
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ class Migration(migrations.Migration):
|
|||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
('updated_at', models.DateTimeField(auto_now=True)),
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('is_deleted', models.BooleanField(default=False)),
|
||||||
('name', models.CharField(max_length=200)),
|
('name', models.CharField(max_length=200)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from django.db import models
|
|||||||
class BaseModel(models.Model):
|
class BaseModel(models.Model):
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
is_deleted = models.BooleanField(default=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# django
|
|
||||||
from django.contrib import admin
|
|
||||||
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
|
|
||||||
|
|
||||||
|
|
||||||
# shared_accounts
|
|
||||||
from core.apps.shared_accounts.models.user import AdminUser
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AdminUser)
|
|
||||||
class UserAdmin(DjangoUserAdmin):
|
|
||||||
fieldsets = (
|
|
||||||
(None, {"fields": ("username", "password")}),
|
|
||||||
(("Personal info"), {"fields": ("first_name", "last_name", "email")}),
|
|
||||||
(
|
|
||||||
("Permissions"),
|
|
||||||
{
|
|
||||||
"fields": (
|
|
||||||
"is_active",
|
|
||||||
"is_staff",
|
|
||||||
"is_superuser",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(("Important dates"), {"fields": ("last_login", "date_joined")}),
|
|
||||||
)
|
|
||||||
add_fieldsets = (
|
|
||||||
(
|
|
||||||
None,
|
|
||||||
{
|
|
||||||
"classes": ("wide",),
|
|
||||||
"fields": ("username", "password1", "password2"),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
list_display = ("username", "first_name", "last_name", "is_staff")
|
|
||||||
list_filter = ("is_staff", "is_superuser", "is_active",)
|
|
||||||
search_fields = ("username", "first_name", "last_name", "email")
|
|
||||||
ordering = ("username",)
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class SharedAccountsConfig(AppConfig):
|
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
|
||||||
name = 'core.apps.shared_accounts'
|
|
||||||
|
|
||||||
def ready(self):
|
|
||||||
import core.apps.shared_accounts.admin
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# Generated by Django 5.2 on 2025-12-07 09:47
|
|
||||||
|
|
||||||
import django.contrib.auth.models
|
|
||||||
import django.contrib.auth.validators
|
|
||||||
import django.utils.timezone
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('auth', '0012_alter_user_first_name_max_length'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='AdminUser',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
|
||||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
|
||||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
|
||||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
|
||||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
|
||||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
|
||||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
|
||||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
|
||||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
|
||||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
||||||
('updated_at', models.DateTimeField(auto_now=True)),
|
|
||||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
|
||||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'Admin User',
|
|
||||||
'verbose_name_plural': 'Admin Users',
|
|
||||||
},
|
|
||||||
managers=[
|
|
||||||
('objects', django.contrib.auth.models.UserManager()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# django
|
|
||||||
from django.db import models
|
|
||||||
from django.contrib.auth.models import AbstractUser
|
|
||||||
|
|
||||||
|
|
||||||
# shared
|
|
||||||
from core.apps.shared.models import BaseModel
|
|
||||||
|
|
||||||
|
|
||||||
class AdminUser(AbstractUser, BaseModel):
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.first_name} {self.last_name}"
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Admin User"
|
|
||||||
verbose_name_plural = "Admin Users"
|
|
||||||
12
core/utils/permissions/tenant_user.py
Normal file
12
core/utils/permissions/tenant_user.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# rest framework
|
||||||
|
from rest_framework.permissions import BasePermission
|
||||||
|
|
||||||
|
|
||||||
|
class IsTenantUser(BasePermission):
|
||||||
|
"""
|
||||||
|
Allow access only if request.tenant_user exists.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
|
||||||
|
return bool(request.tenant_user)
|
||||||
@@ -1 +1 @@
|
|||||||
from .mixin import ResponseMixin
|
from .mixin import *
|
||||||
@@ -31,7 +31,7 @@ class ResponseMixin:
|
|||||||
return Response(response_data, status=response_data["status_code"])
|
return Response(response_data, status=response_data["status_code"])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def failure_response(cls, data=None, message=None):
|
def failure_response(cls, data=None):
|
||||||
"""
|
"""
|
||||||
Docstring for failure_response
|
Docstring for failure_response
|
||||||
|
|
||||||
@@ -43,8 +43,7 @@ class ResponseMixin:
|
|||||||
"status_code": status.HTTP_400_BAD_REQUEST,
|
"status_code": status.HTTP_400_BAD_REQUEST,
|
||||||
"status": cls.FAILURE
|
"status": cls.FAILURE
|
||||||
}
|
}
|
||||||
if message is not None:
|
response_data["message"] = "Kiritayotgan malumotingizni tekshirib ko'ring"
|
||||||
response_data["message"] = message
|
|
||||||
if data is not None:
|
if data is not None:
|
||||||
response_data["data"] = data
|
response_data["data"] = data
|
||||||
return
|
return
|
||||||
@@ -105,7 +104,7 @@ class ResponseMixin:
|
|||||||
return Response(response_data, status=response_data['status_code'])
|
return Response(response_data, status=response_data['status_code'])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def error_response(cls, data=None, message=None):
|
def error_response(cls, data=None):
|
||||||
"""
|
"""
|
||||||
Docstring for error_response
|
Docstring for error_response
|
||||||
|
|
||||||
@@ -117,8 +116,9 @@ class ResponseMixin:
|
|||||||
"status_code": status.HTTP_500_INTERNAL_SERVER_ERROR,
|
"status_code": status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
"status": cls.ERROR
|
"status": cls.ERROR
|
||||||
}
|
}
|
||||||
if message is not None:
|
response_data["message"] = "Xatolik, Iltimos backend dasturchiga murojaat qiling"
|
||||||
response_data["message"] = message
|
|
||||||
if data is not None:
|
if data is not None:
|
||||||
response_data["data"] = data
|
response_data["data"] = data
|
||||||
|
|
||||||
return Response(response_data, status=response_data["status_code"])
|
return Response(response_data, status=response_data["status_code"])
|
||||||
Reference in New Issue
Block a user