From 1211f6ebb5dc356044f3f0085ba933d5076ef6b9 Mon Sep 17 00:00:00 2001 From: muhammadvadud Date: Thu, 27 Nov 2025 12:02:34 +0500 Subject: [PATCH] Banner api lari tayyor --- core/apps/api/admin/__init__.py | 1 + core/apps/api/admin/banner/__init__.py | 1 + core/apps/api/admin/banner/banner.py | 12 ++++ core/apps/api/models/banner/banner.py | 5 ++ core/apps/api/serializers/__init__.py | 1 + core/apps/api/serializers/banner/__init__.py | 1 + core/apps/api/serializers/banner/banner.py | 28 ++++++++++ core/apps/api/tests/__init__.py | 1 + core/apps/api/tests/banner/__init__.py | 1 + core/apps/api/tests/banner/test_banner.py | 58 ++++++++++++++++++++ core/apps/api/urls.py | 3 +- core/apps/api/views/__init__.py | 1 + core/apps/api/views/banner/__init__.py | 1 + core/apps/api/views/banner/banner.py | 25 +++++++++ 14 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 core/apps/api/admin/banner/__init__.py create mode 100644 core/apps/api/admin/banner/banner.py create mode 100644 core/apps/api/serializers/banner/__init__.py create mode 100644 core/apps/api/serializers/banner/banner.py create mode 100644 core/apps/api/tests/banner/__init__.py create mode 100644 core/apps/api/tests/banner/test_banner.py create mode 100644 core/apps/api/views/banner/__init__.py create mode 100644 core/apps/api/views/banner/banner.py diff --git a/core/apps/api/admin/__init__.py b/core/apps/api/admin/__init__.py index 6929f87..ac659ee 100644 --- a/core/apps/api/admin/__init__.py +++ b/core/apps/api/admin/__init__.py @@ -2,3 +2,4 @@ from .category import * # noqa from .ad import * # noqa from .ad_items import * # noqa from .feedback import * # noqa +from .banner import * # noqa diff --git a/core/apps/api/admin/banner/__init__.py b/core/apps/api/admin/banner/__init__.py new file mode 100644 index 0000000..1b144fd --- /dev/null +++ b/core/apps/api/admin/banner/__init__.py @@ -0,0 +1 @@ +from .banner import * # noqa diff --git a/core/apps/api/admin/banner/banner.py b/core/apps/api/admin/banner/banner.py new file mode 100644 index 0000000..c67e111 --- /dev/null +++ b/core/apps/api/admin/banner/banner.py @@ -0,0 +1,12 @@ +from django.contrib import admin +from unfold.admin import ModelAdmin + +from core.apps.api.models import Banner + + +@admin.register(Banner) +class BannerAdmin(ModelAdmin): + list_display = ( + "id", + "__str__", + ) diff --git a/core/apps/api/models/banner/banner.py b/core/apps/api/models/banner/banner.py index 297d004..e2babe0 100644 --- a/core/apps/api/models/banner/banner.py +++ b/core/apps/api/models/banner/banner.py @@ -1,6 +1,7 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from django_core.models.base import AbstractBaseModel +from model_bakery import baker class Banner(AbstractBaseModel): @@ -12,6 +13,10 @@ class Banner(AbstractBaseModel): bg_color = models.CharField(verbose_name=_("BG Color"), max_length=255) text_color = models.CharField(verbose_name=_("Text Color"), max_length=255) + @classmethod + def _baker(cls): + return baker.make(cls) + def __str__(self): return str(self.pk) diff --git a/core/apps/api/serializers/__init__.py b/core/apps/api/serializers/__init__.py index 0ffa197..29847a6 100644 --- a/core/apps/api/serializers/__init__.py +++ b/core/apps/api/serializers/__init__.py @@ -3,3 +3,4 @@ from .search import * # noqa from .ad import * # noqa from .user import * # noqa from .notification import * # noqa +from .banner import * # noqa diff --git a/core/apps/api/serializers/banner/__init__.py b/core/apps/api/serializers/banner/__init__.py new file mode 100644 index 0000000..1b144fd --- /dev/null +++ b/core/apps/api/serializers/banner/__init__.py @@ -0,0 +1 @@ +from .banner import * # noqa diff --git a/core/apps/api/serializers/banner/banner.py b/core/apps/api/serializers/banner/banner.py new file mode 100644 index 0000000..cb37326 --- /dev/null +++ b/core/apps/api/serializers/banner/banner.py @@ -0,0 +1,28 @@ +from rest_framework import serializers +from core.apps.api.models import Banner + + +class BaseBannerSerializer(serializers.ModelSerializer): + class Meta: + model = Banner + fields = [ + "title", + "description", + "mobile_image", + "desktop_image", + "link", + "bg_color", + "text_color", + ] + + +class ListBannerSerializer(BaseBannerSerializer): + class Meta(BaseBannerSerializer.Meta): ... + + +class RetrieveBannerSerializer(BaseBannerSerializer): + class Meta(BaseBannerSerializer.Meta): ... + + +class CreateBannerSerializer(BaseBannerSerializer): + class Meta(BaseBannerSerializer.Meta): ... diff --git a/core/apps/api/tests/__init__.py b/core/apps/api/tests/__init__.py index 8d96b9f..c2b0648 100644 --- a/core/apps/api/tests/__init__.py +++ b/core/apps/api/tests/__init__.py @@ -2,3 +2,4 @@ from .category import * # noqa from .ad import * # noqa from .search import * # noqa from .user import * # noqa +from .banner import * # noqa diff --git a/core/apps/api/tests/banner/__init__.py b/core/apps/api/tests/banner/__init__.py new file mode 100644 index 0000000..0b9c46b --- /dev/null +++ b/core/apps/api/tests/banner/__init__.py @@ -0,0 +1 @@ +from .test_banner import * # noqa diff --git a/core/apps/api/tests/banner/test_banner.py b/core/apps/api/tests/banner/test_banner.py new file mode 100644 index 0000000..b71bad1 --- /dev/null +++ b/core/apps/api/tests/banner/test_banner.py @@ -0,0 +1,58 @@ +import pytest +from django.urls import reverse +from rest_framework.test import APIClient + +from core.apps.api.models import Banner + + +@pytest.fixture +def instance(db): + return Banner._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("banner-list"), + "retrieve": reverse("banner-detail", kwargs={"pk": instance.pk}), + "retrieve-not-found": reverse("banner-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 diff --git a/core/apps/api/urls.py b/core/apps/api/urls.py index d3dd93f..f07350d 100644 --- a/core/apps/api/urls.py +++ b/core/apps/api/urls.py @@ -2,9 +2,10 @@ from django.urls import include, path from rest_framework.routers import DefaultRouter from core.apps.api.views import CategoryHomeApiViewSet, CategoryViewSet, HomeAdApiView, SearchHistoryViewSet, \ - UserLikeViewSet, NotificationViewSet + UserLikeViewSet, NotificationViewSet, BannerViewSet router = DefaultRouter() +router.register("banner", BannerViewSet, basename="banner") router.register("notification", NotificationViewSet, basename="notification") router.register("user-like", UserLikeViewSet, basename="user-like") router.register("category", CategoryViewSet, basename="category") diff --git a/core/apps/api/views/__init__.py b/core/apps/api/views/__init__.py index 0ffa197..29847a6 100644 --- a/core/apps/api/views/__init__.py +++ b/core/apps/api/views/__init__.py @@ -3,3 +3,4 @@ from .search import * # noqa from .ad import * # noqa from .user import * # noqa from .notification import * # noqa +from .banner import * # noqa diff --git a/core/apps/api/views/banner/__init__.py b/core/apps/api/views/banner/__init__.py new file mode 100644 index 0000000..1b144fd --- /dev/null +++ b/core/apps/api/views/banner/__init__.py @@ -0,0 +1 @@ +from .banner import * # noqa diff --git a/core/apps/api/views/banner/banner.py b/core/apps/api/views/banner/banner.py new file mode 100644 index 0000000..db700ad --- /dev/null +++ b/core/apps/api/views/banner/banner.py @@ -0,0 +1,25 @@ +from rest_framework.permissions import IsAuthenticated, AllowAny +from rest_framework.viewsets import ReadOnlyModelViewSet +from drf_spectacular.utils import extend_schema +from django_core.mixins import BaseViewSetMixin + +from core.apps.api.models import Banner +from core.apps.api.serializers.banner import ( + ListBannerSerializer, + RetrieveBannerSerializer, + CreateBannerSerializer, +) + + +@extend_schema(tags=['Banner']) +class BannerViewSet(BaseViewSetMixin, ReadOnlyModelViewSet): + queryset = Banner.objects.all() + serializer_class = ListBannerSerializer + permission_classes = [AllowAny] + + action_permission_classes = {} + action_serializers = { + 'list': ListBannerSerializer, + 'retrieve': RetrieveBannerSerializer, + 'create': CreateBannerSerializer, + }