add: add product and category models
This commit is contained in:
@@ -4,6 +4,6 @@ REST_FRAMEWORK = {
|
|||||||
'rest_framework.authentication.BasicAuthentication',
|
'rest_framework.authentication.BasicAuthentication',
|
||||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
||||||
],
|
],
|
||||||
# 'DEFAULT_PAGINATION_CLASS': 'core.apps.shared.paginations.custom.CustomPageNumberPagination',
|
'DEFAULT_PAGINATION_CLASS': 'core.apps.shared.paginations.custom.CustomPageNumberPagination',
|
||||||
# 'PAGE_SIZE': 10
|
'PAGE_SIZE': 10
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
|
|||||||
|
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'modeltranslation',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
@@ -110,4 +111,14 @@ MEDIA_ROOT = BASE_DIR / 'resources/media'
|
|||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
from config.conf import *
|
AUTH_USER_MODEL = 'accounts.User'
|
||||||
|
|
||||||
|
|
||||||
|
from config.conf import *
|
||||||
|
|
||||||
|
LANGUAGES = (
|
||||||
|
('uz', 'Uzbek'),
|
||||||
|
('ru', 'Russian'),
|
||||||
|
)
|
||||||
|
MODELTRANSLATION_LANGUAGES = ('uz', 'ru')
|
||||||
|
MODELTRANSLATION_DEFAULT_LANGUAGE = 'uz'
|
||||||
46
core/apps/accounts/migrations/0001_initial.py
Normal file
46
core/apps/accounts/migrations/0001_initial.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-28 16:06
|
||||||
|
|
||||||
|
import django.contrib.auth.models
|
||||||
|
import django.contrib.auth.validators
|
||||||
|
import django.utils.timezone
|
||||||
|
import uuid
|
||||||
|
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='User',
|
||||||
|
fields=[
|
||||||
|
('created_at', models.DateTimeField(auto_created=True)),
|
||||||
|
('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')),
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=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': 'user',
|
||||||
|
'verbose_name_plural': 'users',
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
managers=[
|
||||||
|
('objects', django.contrib.auth.models.UserManager()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
18
core/apps/accounts/migrations/0002_alter_user_created_at.py
Normal file
18
core/apps/accounts/migrations/0002_alter_user_created_at.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-28 16:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounts', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='created_at',
|
||||||
|
field=models.DateTimeField(auto_now_add=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .user import *
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
||||||
|
from rest_framework_simplejwt.views import TokenObtainPairView
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('login/', TokenObtainPairView.as_view()),
|
||||||
]
|
]
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
from .product import *
|
||||||
|
from .category import *
|
||||||
11
core/apps/products/admin/category.py
Normal file
11
core/apps/products/admin/category.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from modeltranslation.admin import TranslationAdmin
|
||||||
|
|
||||||
|
from core.apps.products.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Category)
|
||||||
|
class CategoryAdmin(TranslationAdmin):
|
||||||
|
list_display = ['id', 'name']
|
||||||
|
|
||||||
11
core/apps/products/admin/product.py
Normal file
11
core/apps/products/admin/product.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from modeltranslation.admin import TranslationAdmin
|
||||||
|
|
||||||
|
from core.apps.products.models import Product
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Product)
|
||||||
|
class ProductAdmin(TranslationAdmin):
|
||||||
|
list_display = ['id', 'name', 'price', 'category']
|
||||||
|
list_filter = ['category']
|
||||||
@@ -4,3 +4,6 @@ from django.apps import AppConfig
|
|||||||
class ProductsConfig(AppConfig):
|
class ProductsConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'core.apps.products'
|
name = 'core.apps.products'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from . import admin, translation
|
||||||
45
core/apps/products/migrations/0001_initial.py
Normal file
45
core/apps/products/migrations/0001_initial.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-28 16:17
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Category',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('image', models.ImageField(upload_to='products/category/')),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Kategoriya',
|
||||||
|
'verbose_name_plural': 'Kategoriyalar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Product',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
('image', models.ImageField(upload_to='products/product/')),
|
||||||
|
('price', models.PositiveBigIntegerField()),
|
||||||
|
('description', models.TextField(blank=True, null=True)),
|
||||||
|
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='products', to='products.category')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Mahsulot',
|
||||||
|
'verbose_name_plural': 'Mahsulotlar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-28 16:22
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('products', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='category',
|
||||||
|
name='name_ru',
|
||||||
|
field=models.CharField(max_length=200, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='category',
|
||||||
|
name='name_uz',
|
||||||
|
field=models.CharField(max_length=200, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='product',
|
||||||
|
name='description_ru',
|
||||||
|
field=models.TextField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='product',
|
||||||
|
name='description_uz',
|
||||||
|
field=models.TextField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='product',
|
||||||
|
name='name_ru',
|
||||||
|
field=models.CharField(max_length=200, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='product',
|
||||||
|
name='name_uz',
|
||||||
|
field=models.CharField(max_length=200, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
from .category import *
|
||||||
|
from .product import *
|
||||||
18
core/apps/products/models/category.py
Normal file
18
core/apps/products/models/category.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from core.apps.shared.models.base import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Category(BaseModel):
|
||||||
|
image = models.ImageField(upload_to='products/category/')
|
||||||
|
name = models.CharField(max_length=200)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Kategoriya'
|
||||||
|
verbose_name_plural = 'Kategoriyalar'
|
||||||
|
|
||||||
|
|
||||||
20
core/apps/products/models/product.py
Normal file
20
core/apps/products/models/product.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from core.apps.shared.models.base import BaseModel
|
||||||
|
from core.apps.products.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
class Product(BaseModel):
|
||||||
|
name = models.CharField(max_length=200)
|
||||||
|
image = models.ImageField(upload_to='products/product/')
|
||||||
|
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
|
||||||
|
price = models.PositiveBigIntegerField()
|
||||||
|
description = models.TextField(null=True, blank=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Mahsulot'
|
||||||
|
verbose_name_plural = 'Mahsulotlar'
|
||||||
|
|
||||||
11
core/apps/products/serializers/category.py
Normal file
11
core/apps/products/serializers/category.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.products.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryListSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Category
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'image'
|
||||||
|
]
|
||||||
11
core/apps/products/serializers/product.py
Normal file
11
core/apps/products/serializers/product.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.products.models import Product
|
||||||
|
|
||||||
|
|
||||||
|
class ProductListSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Product
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'image', 'price', 'description',
|
||||||
|
]
|
||||||
2
core/apps/products/translation/__init__.py
Normal file
2
core/apps/products/translation/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from .product import *
|
||||||
|
from .category import *
|
||||||
10
core/apps/products/translation/category.py
Normal file
10
core/apps/products/translation/category.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from modeltranslation import translator
|
||||||
|
|
||||||
|
from core.apps.products.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
@translator.register(Category)
|
||||||
|
class CategoryTranslation(translator.TranslationOptions):
|
||||||
|
fields = [
|
||||||
|
'name'
|
||||||
|
]
|
||||||
10
core/apps/products/translation/product.py
Normal file
10
core/apps/products/translation/product.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from modeltranslation import translator
|
||||||
|
|
||||||
|
from core.apps.products.models import Product
|
||||||
|
|
||||||
|
|
||||||
|
@translator.register(Product)
|
||||||
|
class ProductTranslation(translator.TranslationOptions):
|
||||||
|
fields = [
|
||||||
|
'name', 'description'
|
||||||
|
]
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
||||||
|
from core.apps.products.views import category as category_veiws
|
||||||
|
from core.apps.products.views import product as product_views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('category/', include(
|
||||||
|
[
|
||||||
|
path('list/', category_veiws.CategoryListApiView.as_view()),
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
path('product/', include(
|
||||||
|
[
|
||||||
|
path('<uuid:category_id>/list/', product_views.ProductListApiView.as_view()),
|
||||||
|
]
|
||||||
|
))
|
||||||
]
|
]
|
||||||
23
core/apps/products/views/category.py
Normal file
23
core/apps/products/views/category.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from rest_framework import generics, permissions
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from core.apps.products.models import Category
|
||||||
|
from core.apps.products.serializers import category as serializers
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryListApiView(generics.GenericAPIView):
|
||||||
|
serializer_class = serializers.CategoryListSerializer
|
||||||
|
queryset = Category.objects.all()
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
category = self.get_queryset()
|
||||||
|
page = self.paginate_queryset(category)
|
||||||
|
if page is not None:
|
||||||
|
serializer = self.serializer_class(page, many=True)
|
||||||
|
return self.get_paginated_response(serializer.data)
|
||||||
|
serializer = self.serializer_class(category, many=True)
|
||||||
|
return Response(serializer.data, status=200)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
23
core/apps/products/views/product.py
Normal file
23
core/apps/products/views/product.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from rest_framework import generics
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from core.apps.products.models import Product, Category
|
||||||
|
from core.apps.products.serializers import category as serializers
|
||||||
|
|
||||||
|
|
||||||
|
class ProductListApiView(generics.GenericAPIView):
|
||||||
|
serializer_class = serializers.CategoryListSerializer
|
||||||
|
queryset = Product.objects.all()
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def get(self, request, category_id):
|
||||||
|
category = get_object_or_404(Category, id=category_id)
|
||||||
|
products = Product.objects.filter(category=category)
|
||||||
|
page = self.paginate_queryset(products)
|
||||||
|
if page is not None:
|
||||||
|
serializer = self.serializer_class(page, many=True)
|
||||||
|
return self.get_paginated_response(serializer.data)
|
||||||
|
serializer = self.serializer_class(products, many=True)
|
||||||
|
return Response(serializer.data, status=200)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .banner import *
|
||||||
9
core/apps/shared/admin/banner.py
Normal file
9
core/apps/shared/admin/banner.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from core.apps.shared.models import Banner
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Banner)
|
||||||
|
class BannerAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['id', 'banner']
|
||||||
|
|
||||||
@@ -4,3 +4,6 @@ from django.apps import AppConfig
|
|||||||
class SharedConfig(AppConfig):
|
class SharedConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'core.apps.shared'
|
name = 'core.apps.shared'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from . import admin
|
||||||
27
core/apps/shared/migrations/0001_initial.py
Normal file
27
core/apps/shared/migrations/0001_initial.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-28 16:17
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Banner',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('banner', models.ImageField(upload_to='shared/banners/')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'banner',
|
||||||
|
'verbose_name_plural': 'bannerlar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
from .base import *
|
||||||
|
from .banner import *
|
||||||
11
core/apps/shared/models/banner.py
Normal file
11
core/apps/shared/models/banner.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from core.apps.shared.models import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class Banner(BaseModel):
|
||||||
|
banner = models.ImageField(upload_to='shared/banners/')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'banner'
|
||||||
|
verbose_name_plural = 'bannerlar'
|
||||||
@@ -6,7 +6,7 @@ from django.db import models
|
|||||||
|
|
||||||
class BaseModel(models.Model):
|
class BaseModel(models.Model):
|
||||||
id = models.UUIDField(primary_key=True, editable=False, unique=True, default=uuid.uuid4)
|
id = models.UUIDField(primary_key=True, editable=False, unique=True, default=uuid.uuid4)
|
||||||
created_at = models.DateTimeField(auto_created=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|||||||
22
core/apps/shared/paginations/custom.py
Normal file
22
core/apps/shared/paginations/custom.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
|
||||||
|
|
||||||
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
class CustomPageNumberPagination(PageNumberPagination):
|
||||||
|
page_size = 10
|
||||||
|
page_query_param = 'page'
|
||||||
|
page_size_query_param = 'page_size'
|
||||||
|
max_page_size = 100
|
||||||
|
|
||||||
|
def get_paginated_response(self, data):
|
||||||
|
return Response({
|
||||||
|
'total': self.page.paginator.count,
|
||||||
|
'page': self.page.number,
|
||||||
|
'page_size': self.get_page_size(self.request),
|
||||||
|
'total_pages': self.page.paginator.num_pages,
|
||||||
|
'has_next': self.page.has_next(),
|
||||||
|
'has_previous': self.page.has_previous(),
|
||||||
|
'results': data
|
||||||
|
})
|
||||||
@@ -8,4 +8,6 @@ djangorestframework-simplejwt
|
|||||||
drf_yasg
|
drf_yasg
|
||||||
redis
|
redis
|
||||||
django-redis
|
django-redis
|
||||||
psycopg2-binary
|
psycopg2-binary
|
||||||
|
pillow
|
||||||
|
django-modeltranslation
|
||||||
Reference in New Issue
Block a user