diff --git a/=4.12 b/=4.12 new file mode 100644 index 0000000..73ec7fa --- /dev/null +++ b/=4.12 @@ -0,0 +1 @@ +Requirement already satisfied: typing_extensions in ./.venv/lib/python3.12/site-packages (4.12.2) diff --git a/config/settings/common.py b/config/settings/common.py index 7ea8d9b..fd01f4a 100644 --- a/config/settings/common.py +++ b/config/settings/common.py @@ -179,6 +179,9 @@ REST_FRAMEWORK = { "user": "60/min", }, "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + "DEFAULT_AUTHENTICATION_CLASSES": [ + "rest_framework.authentication.TokenAuthentication", + ] } diff --git a/core/apps/accounts/tests/test_auth.py b/core/apps/accounts/tests/test_auth.py index 7b3411a..4c3eed5 100644 --- a/core/apps/accounts/tests/test_auth.py +++ b/core/apps/accounts/tests/test_auth.py @@ -40,9 +40,8 @@ def sms_code(test_user): def test_reg_view(api_client): data = { "phone": "998999999991", - "first_name": "John", - "last_name": "Doe", "password": "password", + "confirm_password":"password" } with patch.object(SmsService, "send_confirm", return_value=True): response = api_client.post(reverse("auth-register"), data=data) diff --git a/core/apps/accounts/views/auth.py b/core/apps/accounts/views/auth.py index 2331305..ffe02f4 100644 --- a/core/apps/accounts/views/auth.py +++ b/core/apps/accounts/views/auth.py @@ -1,6 +1,8 @@ import uuid from typing import Type +from rest_framework.authentication import TokenAuthentication + from core.services import UserService, SmsService from django.contrib.auth import get_user_model from django.utils.translation import gettext_lazy as _ @@ -186,6 +188,7 @@ class MeView(BaseViewSetMixin, GenericViewSet, UserService): class ChangePasswordView(BaseViewSetMixin, GenericViewSet): serializer_class = ChangePasswordSerializer permission_classes = (IsAuthenticated,) + authentication_classes = [TokenAuthentication] @extend_schema( request=serializer_class, diff --git a/core/apps/api/admin/__init__.py b/core/apps/api/admin/__init__.py index e69de29..b4e0216 100644 --- a/core/apps/api/admin/__init__.py +++ b/core/apps/api/admin/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/admin/attributes.py b/core/apps/api/admin/attributes.py new file mode 100644 index 0000000..59a72fb --- /dev/null +++ b/core/apps/api/admin/attributes.py @@ -0,0 +1,28 @@ +from django.contrib import admin +from unfold.admin import ModelAdmin + +from core.apps.api.models import ColorModel, ProductlikeModel, SizeModel + + +@admin.register(SizeModel) +class SizeAdmin(ModelAdmin): + list_display = ( + "id", + "__str__", + ) + + +@admin.register(ColorModel) +class ColorAdmin(ModelAdmin): + list_display = ( + "id", + "__str__", + ) + + +@admin.register(ProductlikeModel) +class ProductlikeAdmin(ModelAdmin): + list_display = ( + "id", + "__str__", + ) diff --git a/core/apps/api/filters/__init__.py b/core/apps/api/filters/__init__.py new file mode 100644 index 0000000..b4e0216 --- /dev/null +++ b/core/apps/api/filters/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/filters/attributes.py b/core/apps/api/filters/attributes.py new file mode 100644 index 0000000..45cccf9 --- /dev/null +++ b/core/apps/api/filters/attributes.py @@ -0,0 +1,33 @@ +from django_filters import rest_framework as filters + +from core.apps.api.models import ColorModel, ProductlikeModel, SizeModel + + +class SizeFilter(filters.FilterSet): + # name = filters.CharFilter(field_name="name", lookup_expr="icontains") + + class Meta: + model = SizeModel + fields = [ + "name", + ] + + +class ColorFilter(filters.FilterSet): + # name = filters.CharFilter(field_name="name", lookup_expr="icontains") + + class Meta: + model = ColorModel + fields = [ + "name", + ] + + +class ProductlikeFilter(filters.FilterSet): + # name = filters.CharFilter(field_name="name", lookup_expr="icontains") + + class Meta: + model = ProductlikeModel + fields = [ + "name", + ] diff --git a/core/apps/api/forms/__init__.py b/core/apps/api/forms/__init__.py new file mode 100644 index 0000000..b4e0216 --- /dev/null +++ b/core/apps/api/forms/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/forms/attributes.py b/core/apps/api/forms/attributes.py new file mode 100644 index 0000000..e1f02ef --- /dev/null +++ b/core/apps/api/forms/attributes.py @@ -0,0 +1,24 @@ +from django import forms + +from core.apps.api.models import ColorModel, ProductlikeModel, SizeModel + + +class SizeForm(forms.ModelForm): + + class Meta: + model = SizeModel + fields = "__all__" + + +class ColorForm(forms.ModelForm): + + class Meta: + model = ColorModel + fields = "__all__" + + +class ProductlikeForm(forms.ModelForm): + + class Meta: + model = ProductlikeModel + fields = "__all__" diff --git a/core/apps/api/migrations/0001_initial.py b/core/apps/api/migrations/0001_initial.py new file mode 100644 index 0000000..552a36b --- /dev/null +++ b/core/apps/api/migrations/0001_initial.py @@ -0,0 +1,57 @@ +# Generated by Django 5.2.7 on 2026-03-09 07:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ColorModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('code', models.CharField(max_length=255, verbose_name='name')), + ], + options={ + 'verbose_name': 'ColorModel', + 'verbose_name_plural': 'ColorModels', + 'db_table': 'color', + }, + ), + migrations.CreateModel( + name='ProductlikeModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=255, verbose_name='name')), + ], + options={ + 'verbose_name': 'ProductlikeModel', + 'verbose_name_plural': 'ProductlikeModels', + 'db_table': 'productlike', + }, + ), + migrations.CreateModel( + name='SizeModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=255, verbose_name='name')), + ], + options={ + 'verbose_name': 'SizeModel', + 'verbose_name_plural': 'SizeModels', + 'db_table': 'size', + }, + ), + ] diff --git a/core/apps/api/models/__init__.py b/core/apps/api/models/__init__.py index e69de29..b4e0216 100644 --- a/core/apps/api/models/__init__.py +++ b/core/apps/api/models/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/models/attributes.py b/core/apps/api/models/attributes.py new file mode 100644 index 0000000..1590c14 --- /dev/null +++ b/core/apps/api/models/attributes.py @@ -0,0 +1,55 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ +from django_core.models import AbstractBaseModel +from model_bakery import baker + + +class SizeModel(AbstractBaseModel): + + name = models.CharField(verbose_name=_("name"), max_length=255) + + def __str__(self): + return str(self.pk) + + @classmethod + def _baker(cls): + return baker.make(cls) + + class Meta: + db_table = "size" + verbose_name = _("SizeModel") + verbose_name_plural = _("SizeModels") + + +class ColorModel(AbstractBaseModel): + + name = models.CharField(verbose_name=_("name"), max_length=255) + code = models.CharField(verbose_name=_("name"), max_length=255) + def __str__(self): + return str(self.pk) + + @classmethod + def _baker(cls): + return baker.make(cls) + + class Meta: + db_table = "color" + verbose_name = _("ColorModel") + verbose_name_plural = _("ColorModels") + + +class ProductlikeModel(AbstractBaseModel): + + name = models.CharField(verbose_name=_("name"), max_length=255) + + def __str__(self): + return str(self.pk) + + @classmethod + def _baker(cls): + return baker.make(cls) + + class Meta: + db_table = "productlike" + verbose_name = _("ProductlikeModel") + verbose_name_plural = _("ProductlikeModels") diff --git a/core/apps/api/permissions/__init__.py b/core/apps/api/permissions/__init__.py new file mode 100644 index 0000000..b4e0216 --- /dev/null +++ b/core/apps/api/permissions/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/permissions/attributes.py b/core/apps/api/permissions/attributes.py new file mode 100644 index 0000000..d824ab0 --- /dev/null +++ b/core/apps/api/permissions/attributes.py @@ -0,0 +1,34 @@ +from rest_framework import permissions + + +class SizePermission(permissions.BasePermission): + + def __init__(self) -> None: ... + + def __call__(self, *args, **kwargs): + return self + + def has_permission(self, request, view): + return True + + +class ColorPermission(permissions.BasePermission): + + def __init__(self) -> None: ... + + def __call__(self, *args, **kwargs): + return self + + def has_permission(self, request, view): + return True + + +class ProductlikePermission(permissions.BasePermission): + + def __init__(self) -> None: ... + + def __call__(self, *args, **kwargs): + return self + + def has_permission(self, request, view): + return True diff --git a/core/apps/api/serializers/__init__.py b/core/apps/api/serializers/__init__.py index e69de29..b4e0216 100644 --- a/core/apps/api/serializers/__init__.py +++ b/core/apps/api/serializers/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/serializers/attributes/__init__.py b/core/apps/api/serializers/attributes/__init__.py new file mode 100644 index 0000000..e7d88f4 --- /dev/null +++ b/core/apps/api/serializers/attributes/__init__.py @@ -0,0 +1,3 @@ +from .color import * # noqa +from .productlike import * # noqa +from .size import * # noqa diff --git a/core/apps/api/serializers/attributes/color.py b/core/apps/api/serializers/attributes/color.py new file mode 100644 index 0000000..162a5fa --- /dev/null +++ b/core/apps/api/serializers/attributes/color.py @@ -0,0 +1,28 @@ +from rest_framework import serializers + +from core.apps.api.models import ColorModel + + +class BaseColorSerializer(serializers.ModelSerializer): + class Meta: + model = ColorModel + fields = [ + "id", + "name", + ] + + +class ListColorSerializer(BaseColorSerializer): + class Meta(BaseColorSerializer.Meta): ... + + +class RetrieveColorSerializer(BaseColorSerializer): + class Meta(BaseColorSerializer.Meta): ... + + +class CreateColorSerializer(BaseColorSerializer): + class Meta(BaseColorSerializer.Meta): + fields = [ + "id", + "name", + ] diff --git a/core/apps/api/serializers/attributes/productlike.py b/core/apps/api/serializers/attributes/productlike.py new file mode 100644 index 0000000..68a5199 --- /dev/null +++ b/core/apps/api/serializers/attributes/productlike.py @@ -0,0 +1,28 @@ +from rest_framework import serializers + +from core.apps.api.models import ProductlikeModel + + +class BaseProductlikeSerializer(serializers.ModelSerializer): + class Meta: + model = ProductlikeModel + fields = [ + "id", + "name", + ] + + +class ListProductlikeSerializer(BaseProductlikeSerializer): + class Meta(BaseProductlikeSerializer.Meta): ... + + +class RetrieveProductlikeSerializer(BaseProductlikeSerializer): + class Meta(BaseProductlikeSerializer.Meta): ... + + +class CreateProductlikeSerializer(BaseProductlikeSerializer): + class Meta(BaseProductlikeSerializer.Meta): + fields = [ + "id", + "name", + ] diff --git a/core/apps/api/serializers/attributes/size.py b/core/apps/api/serializers/attributes/size.py new file mode 100644 index 0000000..996af86 --- /dev/null +++ b/core/apps/api/serializers/attributes/size.py @@ -0,0 +1,28 @@ +from rest_framework import serializers + +from core.apps.api.models import SizeModel + + +class BaseSizeSerializer(serializers.ModelSerializer): + class Meta: + model = SizeModel + fields = [ + "id", + "name", + ] + + +class ListSizeSerializer(BaseSizeSerializer): + class Meta(BaseSizeSerializer.Meta): ... + + +class RetrieveSizeSerializer(BaseSizeSerializer): + class Meta(BaseSizeSerializer.Meta): ... + + +class CreateSizeSerializer(BaseSizeSerializer): + class Meta(BaseSizeSerializer.Meta): + fields = [ + "id", + "name", + ] diff --git a/core/apps/api/signals/__init__.py b/core/apps/api/signals/__init__.py new file mode 100644 index 0000000..b4e0216 --- /dev/null +++ b/core/apps/api/signals/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/signals/attributes.py b/core/apps/api/signals/attributes.py new file mode 100644 index 0000000..50e6321 --- /dev/null +++ b/core/apps/api/signals/attributes.py @@ -0,0 +1,16 @@ +from django.db.models.signals import post_save +from django.dispatch import receiver + +from core.apps.api.models import ColorModel, ProductlikeModel, SizeModel + + +@receiver(post_save, sender=SizeModel) +def SizeSignal(sender, instance, created, **kwargs): ... + + +@receiver(post_save, sender=ColorModel) +def ColorSignal(sender, instance, created, **kwargs): ... + + +@receiver(post_save, sender=ProductlikeModel) +def ProductlikeSignal(sender, instance, created, **kwargs): ... diff --git a/core/apps/api/tests/__init__.py b/core/apps/api/tests/__init__.py index e69de29..b4e0216 100644 --- a/core/apps/api/tests/__init__.py +++ b/core/apps/api/tests/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/tests/attributes/__init__.py b/core/apps/api/tests/attributes/__init__.py new file mode 100644 index 0000000..ae79de5 --- /dev/null +++ b/core/apps/api/tests/attributes/__init__.py @@ -0,0 +1,3 @@ +from .test_color import * # noqa +from .test_productlike import * # noqa +from .test_size import * # noqa diff --git a/core/apps/api/tests/attributes/test_color.py b/core/apps/api/tests/attributes/test_color.py new file mode 100644 index 0000000..ee8bf68 --- /dev/null +++ b/core/apps/api/tests/attributes/test_color.py @@ -0,0 +1,101 @@ +import pytest +from django.urls import reverse +from rest_framework.test import APIClient + +from core.apps.api.models import ColorModel + + +@pytest.fixture +def instance(db): + return ColorModel._baker() + + +@pytest.fixture +def api_client(instance): + client = APIClient() + ##client.force_authenticate(user=instance.user) + return client, instance + + +@pytest.fixture +def data(api_client): + client, instance = api_client + return ( + { + "list": reverse("color-list"), + "retrieve": reverse("color-detail", kwargs={"pk": instance.pk}), + "retrieve-not-found": reverse("color-detail", kwargs={"pk": 1000}), + }, + client, + instance, + ) + + +@pytest.mark.django_db +def test_list(data): + urls, client, _ = data + response = client.get(urls["list"]) + data_resp = response.json() + assert response.status_code == 200 + assert data_resp["status"] is True + + +@pytest.mark.django_db +def test_retrieve(data): + urls, client, _ = data + response = client.get(urls["retrieve"]) + data_resp = response.json() + assert response.status_code == 200 + assert data_resp["status"] is True + + +@pytest.mark.django_db +def test_retrieve_not_found(data): + urls, client, _ = data + response = client.get(urls["retrieve-not-found"]) + data_resp = response.json() + assert response.status_code == 404 + assert data_resp["status"] is False + + +# @pytest.mark.django_db +# def test_create(data): +# urls, client, _ = data +# response = client.post(urls["list"], data={"name": "test"}) +# assert response.json()["status"] is True +# assert response.status_code == 201 + + +# @pytest.mark.django_db +# def test_update(data): +# urls, client, _ = data +# response = client.patch(urls["retrieve"], data={"name": "updated"}) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# +# # verify updated value +# response = client.get(urls["retrieve"]) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# assert response.json()["data"]["name"] == "updated" + + +# @pytest.mark.django_db +# def test_partial_update(): +# urls, client, _ = data +# response = client.patch(urls["retrieve"], data={"name": "updated"}) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# +# # verify updated value +# response = client.get(urls["retrieve"]) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# assert response.json()["data"]["name"] == "updated" + + +# @pytest.mark.django_db +# def test_destroy(data): +# urls, client, _ = data +# response = client.delete(urls["retrieve"]) +# assert response.status_code == 204 diff --git a/core/apps/api/tests/attributes/test_productlike.py b/core/apps/api/tests/attributes/test_productlike.py new file mode 100644 index 0000000..56a0b4b --- /dev/null +++ b/core/apps/api/tests/attributes/test_productlike.py @@ -0,0 +1,101 @@ +import pytest +from django.urls import reverse +from rest_framework.test import APIClient + +from core.apps.api.models import ProductlikeModel + + +@pytest.fixture +def instance(db): + return ProductlikeModel._baker() + + +@pytest.fixture +def api_client(instance): + client = APIClient() + ##client.force_authenticate(user=instance.user) + return client, instance + + +@pytest.fixture +def data(api_client): + client, instance = api_client + return ( + { + "list": reverse("productlike-list"), + "retrieve": reverse("productlike-detail", kwargs={"pk": instance.pk}), + "retrieve-not-found": reverse("productlike-detail", kwargs={"pk": 1000}), + }, + client, + instance, + ) + + +@pytest.mark.django_db +def test_list(data): + urls, client, _ = data + response = client.get(urls["list"]) + data_resp = response.json() + assert response.status_code == 200 + assert data_resp["status"] is True + + +@pytest.mark.django_db +def test_retrieve(data): + urls, client, _ = data + response = client.get(urls["retrieve"]) + data_resp = response.json() + assert response.status_code == 200 + assert data_resp["status"] is True + + +@pytest.mark.django_db +def test_retrieve_not_found(data): + urls, client, _ = data + response = client.get(urls["retrieve-not-found"]) + data_resp = response.json() + assert response.status_code == 404 + assert data_resp["status"] is False + + +# @pytest.mark.django_db +# def test_create(data): +# urls, client, _ = data +# response = client.post(urls["list"], data={"name": "test"}) +# assert response.json()["status"] is True +# assert response.status_code == 201 + + +# @pytest.mark.django_db +# def test_update(data): +# urls, client, _ = data +# response = client.patch(urls["retrieve"], data={"name": "updated"}) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# +# # verify updated value +# response = client.get(urls["retrieve"]) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# assert response.json()["data"]["name"] == "updated" + + +# @pytest.mark.django_db +# def test_partial_update(): +# urls, client, _ = data +# response = client.patch(urls["retrieve"], data={"name": "updated"}) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# +# # verify updated value +# response = client.get(urls["retrieve"]) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# assert response.json()["data"]["name"] == "updated" + + +# @pytest.mark.django_db +# def test_destroy(data): +# urls, client, _ = data +# response = client.delete(urls["retrieve"]) +# assert response.status_code == 204 diff --git a/core/apps/api/tests/attributes/test_size.py b/core/apps/api/tests/attributes/test_size.py new file mode 100644 index 0000000..30236c6 --- /dev/null +++ b/core/apps/api/tests/attributes/test_size.py @@ -0,0 +1,101 @@ +import pytest +from django.urls import reverse +from rest_framework.test import APIClient + +from core.apps.api.models import SizeModel + + +@pytest.fixture +def instance(db): + return SizeModel._baker() + + +@pytest.fixture +def api_client(instance): + client = APIClient() + ##client.force_authenticate(user=instance.user) + return client, instance + + +@pytest.fixture +def data(api_client): + client, instance = api_client + return ( + { + "list": reverse("size-list"), + "retrieve": reverse("size-detail", kwargs={"pk": instance.pk}), + "retrieve-not-found": reverse("size-detail", kwargs={"pk": 1000}), + }, + client, + instance, + ) + + +@pytest.mark.django_db +def test_list(data): + urls, client, _ = data + response = client.get(urls["list"]) + data_resp = response.json() + assert response.status_code == 200 + assert data_resp["status"] is True + + +@pytest.mark.django_db +def test_retrieve(data): + urls, client, _ = data + response = client.get(urls["retrieve"]) + data_resp = response.json() + assert response.status_code == 200 + assert data_resp["status"] is True + + +@pytest.mark.django_db +def test_retrieve_not_found(data): + urls, client, _ = data + response = client.get(urls["retrieve-not-found"]) + data_resp = response.json() + assert response.status_code == 404 + assert data_resp["status"] is False + + +# @pytest.mark.django_db +# def test_create(data): +# urls, client, _ = data +# response = client.post(urls["list"], data={"name": "test"}) +# assert response.json()["status"] is True +# assert response.status_code == 201 + + +# @pytest.mark.django_db +# def test_update(data): +# urls, client, _ = data +# response = client.patch(urls["retrieve"], data={"name": "updated"}) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# +# # verify updated value +# response = client.get(urls["retrieve"]) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# assert response.json()["data"]["name"] == "updated" + + +# @pytest.mark.django_db +# def test_partial_update(): +# urls, client, _ = data +# response = client.patch(urls["retrieve"], data={"name": "updated"}) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# +# # verify updated value +# response = client.get(urls["retrieve"]) +# assert response.json()["status"] is True +# assert response.status_code == 200 +# assert response.json()["data"]["name"] == "updated" + + +# @pytest.mark.django_db +# def test_destroy(data): +# urls, client, _ = data +# response = client.delete(urls["retrieve"]) +# assert response.status_code == 204 diff --git a/core/apps/api/translation/__init__.py b/core/apps/api/translation/__init__.py new file mode 100644 index 0000000..b4e0216 --- /dev/null +++ b/core/apps/api/translation/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/translation/attributes.py b/core/apps/api/translation/attributes.py new file mode 100644 index 0000000..a7e77e0 --- /dev/null +++ b/core/apps/api/translation/attributes.py @@ -0,0 +1,18 @@ +from modeltranslation.translator import TranslationOptions, register + +from core.apps.api.models import ColorModel, ProductlikeModel, SizeModel + + +@register(SizeModel) +class SizeTranslation(TranslationOptions): + fields = [] + + +@register(ColorModel) +class ColorTranslation(TranslationOptions): + fields = [] + + +@register(ProductlikeModel) +class ProductlikeTranslation(TranslationOptions): + fields = [] diff --git a/core/apps/api/urls.py b/core/apps/api/urls.py index 5fa41be..a9d27bf 100644 --- a/core/apps/api/urls.py +++ b/core/apps/api/urls.py @@ -1,9 +1,10 @@ -from django.urls import path, include +from django.urls import include, path from rest_framework.routers import DefaultRouter +from .views import ColorView, ProductlikeView, SizeView + router = DefaultRouter() - - -urlpatterns = [ - path("", include(router.urls)), -] +router.register("productlike", ProductlikeView, basename="productlike") +router.register("color", ColorView, basename="color") +router.register("size", SizeView, basename="size") +urlpatterns = [path("", include(router.urls))] diff --git a/core/apps/api/validators/__init__.py b/core/apps/api/validators/__init__.py new file mode 100644 index 0000000..b4e0216 --- /dev/null +++ b/core/apps/api/validators/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/validators/attributes.py b/core/apps/api/validators/attributes.py new file mode 100644 index 0000000..da0ebe1 --- /dev/null +++ b/core/apps/api/validators/attributes.py @@ -0,0 +1,22 @@ +# from django.core.exceptions import ValidationError + + +class SizeValidator: + def __init__(self): ... + + def __call__(self): + return True + + +class ColorValidator: + def __init__(self): ... + + def __call__(self): + return True + + +class ProductlikeValidator: + def __init__(self): ... + + def __call__(self): + return True diff --git a/core/apps/api/views/__init__.py b/core/apps/api/views/__init__.py index e69de29..b4e0216 100644 --- a/core/apps/api/views/__init__.py +++ b/core/apps/api/views/__init__.py @@ -0,0 +1 @@ +from .attributes import * # noqa diff --git a/core/apps/api/views/attributes.py b/core/apps/api/views/attributes.py new file mode 100644 index 0000000..08875ce --- /dev/null +++ b/core/apps/api/views/attributes.py @@ -0,0 +1,59 @@ +from django_core.mixins import BaseViewSetMixin +from drf_spectacular.utils import extend_schema +from rest_framework.permissions import AllowAny +from rest_framework.viewsets import ReadOnlyModelViewSet + +from core.apps.api.models import ColorModel, ProductlikeModel, SizeModel +from core.apps.api.serializers.attributes import ( + CreateColorSerializer, + CreateProductlikeSerializer, + CreateSizeSerializer, + ListColorSerializer, + ListProductlikeSerializer, + ListSizeSerializer, + RetrieveColorSerializer, + RetrieveProductlikeSerializer, + RetrieveSizeSerializer, +) + + +@extend_schema(tags=["size"]) +class SizeView(BaseViewSetMixin, ReadOnlyModelViewSet): + queryset = SizeModel.objects.all() + serializer_class = ListSizeSerializer + permission_classes = [AllowAny] + + action_permission_classes = {} + action_serializer_class = { + "list": ListSizeSerializer, + "retrieve": RetrieveSizeSerializer, + "create": CreateSizeSerializer, + } + + +@extend_schema(tags=["color"]) +class ColorView(BaseViewSetMixin, ReadOnlyModelViewSet): + queryset = ColorModel.objects.all() + serializer_class = ListColorSerializer + permission_classes = [AllowAny] + + action_permission_classes = {} + action_serializer_class = { + "list": ListColorSerializer, + "retrieve": RetrieveColorSerializer, + "create": CreateColorSerializer, + } + + +@extend_schema(tags=["productlike"]) +class ProductlikeView(BaseViewSetMixin, ReadOnlyModelViewSet): + queryset = ProductlikeModel.objects.all() + serializer_class = ListProductlikeSerializer + permission_classes = [AllowAny] + + action_permission_classes = {} + action_serializer_class = { + "list": ListProductlikeSerializer, + "retrieve": RetrieveProductlikeSerializer, + "create": CreateProductlikeSerializer, + }