From 5632e0c4848da6748053c35b353a96f77cc62716 Mon Sep 17 00:00:00 2001 From: muhammadvadud Date: Mon, 24 Nov 2025 11:46:23 +0500 Subject: [PATCH] Modellar tayyor --- config/conf/modules.py | 4 +- config/urls.py | 37 +-- core/apps/accounts/choices/__init__.py | 1 + .../accounts/choices/notification_type.py | 11 + core/apps/accounts/choices/user.py | 7 + .../0002_user_account_type_user_is_verify.py | 23 ++ core/apps/accounts/migrations/0003_address.py | 30 +++ .../migrations/0004_business_searchhistory.py | 54 ++++ core/apps/accounts/models/__init__.py | 4 + core/apps/accounts/models/address.py | 18 ++ core/apps/accounts/models/business.py | 26 ++ core/apps/accounts/models/notification.py | 35 +++ core/apps/accounts/models/search_history.py | 17 ++ core/apps/accounts/models/user.py | 4 +- core/apps/accounts/models/user_like.py | 0 core/apps/accounts/models/user_plan.py | 31 +++ core/apps/api/__init__.py | 0 core/apps/api/admin/__init__.py | 0 core/apps/api/apps.py | 6 + core/apps/api/choices/__init__.py | 3 + core/apps/api/choices/ad_type.py | 22 ++ core/apps/api/choices/ad_variant_type.py | 11 + core/apps/api/choices/order_status.py | 12 + core/apps/api/enums/__init__.py | 0 core/apps/api/migrations/0001_initial.py | 34 +++ ...dmodel_adimage_adoption_adsize_and_more.py | 240 ++++++++++++++++++ core/apps/api/migrations/__init__.py | 0 core/apps/api/models/__init__.py | 5 + core/apps/api/models/ad/__init__.py | 2 + core/apps/api/models/ad/ad.py | 38 +++ core/apps/api/models/ad/category.py | 18 ++ core/apps/api/models/ad_items/__init__.py | 6 + core/apps/api/models/ad_items/ad_images.py | 17 ++ core/apps/api/models/ad_items/ad_option.py | 18 ++ core/apps/api/models/ad_items/ad_size.py | 20 ++ core/apps/api/models/ad_items/ad_top_plan.py | 16 ++ core/apps/api/models/ad_items/ad_variant.py | 22 ++ core/apps/api/models/ad_items/tags.py | 15 ++ core/apps/api/models/banner/__init__.py | 1 + core/apps/api/models/banner/banner.py | 21 ++ core/apps/api/models/feedback/__init__.py | 1 + core/apps/api/models/feedback/feedback.py | 34 +++ core/apps/api/models/order/__init__.py | 1 + core/apps/api/models/order/order.py | 36 +++ core/apps/api/serializers/__init__.py | 0 core/apps/api/tests/__init__.py | 0 core/apps/api/urls.py | 9 + core/apps/api/views/__init__.py | 0 48 files changed, 877 insertions(+), 33 deletions(-) create mode 100644 core/apps/accounts/choices/notification_type.py create mode 100644 core/apps/accounts/migrations/0002_user_account_type_user_is_verify.py create mode 100644 core/apps/accounts/migrations/0003_address.py create mode 100644 core/apps/accounts/migrations/0004_business_searchhistory.py create mode 100644 core/apps/accounts/models/address.py create mode 100644 core/apps/accounts/models/business.py create mode 100644 core/apps/accounts/models/notification.py create mode 100644 core/apps/accounts/models/search_history.py create mode 100644 core/apps/accounts/models/user_like.py create mode 100644 core/apps/accounts/models/user_plan.py create mode 100644 core/apps/api/__init__.py create mode 100644 core/apps/api/admin/__init__.py create mode 100644 core/apps/api/apps.py create mode 100644 core/apps/api/choices/__init__.py create mode 100644 core/apps/api/choices/ad_type.py create mode 100644 core/apps/api/choices/ad_variant_type.py create mode 100644 core/apps/api/choices/order_status.py create mode 100644 core/apps/api/enums/__init__.py create mode 100644 core/apps/api/migrations/0001_initial.py create mode 100644 core/apps/api/migrations/0002_adtopplan_color_tags_admodel_adimage_adoption_adsize_and_more.py create mode 100644 core/apps/api/migrations/__init__.py create mode 100644 core/apps/api/models/__init__.py create mode 100644 core/apps/api/models/ad/__init__.py create mode 100644 core/apps/api/models/ad/ad.py create mode 100644 core/apps/api/models/ad/category.py create mode 100644 core/apps/api/models/ad_items/__init__.py create mode 100644 core/apps/api/models/ad_items/ad_images.py create mode 100644 core/apps/api/models/ad_items/ad_option.py create mode 100644 core/apps/api/models/ad_items/ad_size.py create mode 100644 core/apps/api/models/ad_items/ad_top_plan.py create mode 100644 core/apps/api/models/ad_items/ad_variant.py create mode 100644 core/apps/api/models/ad_items/tags.py create mode 100644 core/apps/api/models/banner/__init__.py create mode 100644 core/apps/api/models/banner/banner.py create mode 100644 core/apps/api/models/feedback/__init__.py create mode 100644 core/apps/api/models/feedback/feedback.py create mode 100644 core/apps/api/models/order/__init__.py create mode 100644 core/apps/api/models/order/order.py create mode 100644 core/apps/api/serializers/__init__.py create mode 100644 core/apps/api/tests/__init__.py create mode 100644 core/apps/api/urls.py create mode 100644 core/apps/api/views/__init__.py diff --git a/config/conf/modules.py b/config/conf/modules.py index 71dad20..f39750e 100644 --- a/config/conf/modules.py +++ b/config/conf/modules.py @@ -1,3 +1 @@ -MODULES = [ - "core.apps.shared", -] +MODULES = ["core.apps.shared", "core.apps.api"] diff --git a/config/urls.py b/config/urls.py index 74072d0..cf3b0af 100644 --- a/config/urls.py +++ b/config/urls.py @@ -2,62 +2,41 @@ All urls configurations tree """ -from config.env import env from django.conf import settings from django.contrib import admin from django.http import HttpResponse from django.urls import include, path, re_path from django.views.static import serve -from drf_spectacular.views import (SpectacularAPIView, SpectacularRedocView, - SpectacularSwaggerView) +from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView + +from config.env import env def home(request): return HttpResponse("OK") -################ -# My apps url -################ + urlpatterns = [ path("health/", home), path("", include("core.apps.accounts.urls")), path("api/", include("core.apps.shared.urls")), + path("api/", include("core.apps.api.urls")), ] - - -################ -# Library urls -################ urlpatterns += [ path("admin/", admin.site.urls), path("accounts/", include("django.contrib.auth.urls")), path("i18n/", include("django.conf.urls.i18n")), - path("ckeditor5/", include("django_ckeditor_5.urls"), name="ck_editor_5_upload_file"), ] - -################ -# Project env debug mode -################ if env.bool("SILK_ENABLED", False): - urlpatterns += [ - path('silk/', include('silk.urls', namespace='silk')) - ] + urlpatterns += [path("silk/", include("silk.urls", namespace="silk"))] if env.str("PROJECT_ENV") == "debug": - - ################ - # Swagger urls - ################ urlpatterns += [ path("schema/", SpectacularAPIView.as_view(), name="schema"), path("swagger/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"), path("redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc"), ] - -################ -# Media urls -################ urlpatterns += [ - re_path(r"static/(?P.*)", serve, {"document_root": settings.STATIC_ROOT}), - re_path(r"media/(?P.*)", serve, {"document_root": settings.MEDIA_ROOT}), + re_path("static/(?P.*)", serve, {"document_root": settings.STATIC_ROOT}), + re_path("media/(?P.*)", serve, {"document_root": settings.MEDIA_ROOT}), ] diff --git a/core/apps/accounts/choices/__init__.py b/core/apps/accounts/choices/__init__.py index 1000b27..50ba851 100644 --- a/core/apps/accounts/choices/__init__.py +++ b/core/apps/accounts/choices/__init__.py @@ -1 +1,2 @@ from .user import * # noqa +from .notification_type import * # noqa diff --git a/core/apps/accounts/choices/notification_type.py b/core/apps/accounts/choices/notification_type.py new file mode 100644 index 0000000..9957fa6 --- /dev/null +++ b/core/apps/accounts/choices/notification_type.py @@ -0,0 +1,11 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + + +class NotificationType(models.TextChoices): + """ + Notification Types + """ + + SYSTEM = "System", _("System") + ANOTHER = "Another", _("Another") diff --git a/core/apps/accounts/choices/user.py b/core/apps/accounts/choices/user.py index b93b918..4de57d8 100644 --- a/core/apps/accounts/choices/user.py +++ b/core/apps/accounts/choices/user.py @@ -10,3 +10,10 @@ class RoleChoice(models.TextChoices): SUPERUSER = "superuser", _("Superuser") ADMIN = "admin", _("Admin") USER = "user", _("User") + +class AccountType(models.TextChoices): + """ + User Account Type + """ + PERSONAL = "personal", _("Personal") + BUSINESS = "business", _("Business") diff --git a/core/apps/accounts/migrations/0002_user_account_type_user_is_verify.py b/core/apps/accounts/migrations/0002_user_account_type_user_is_verify.py new file mode 100644 index 0000000..70b9f04 --- /dev/null +++ b/core/apps/accounts/migrations/0002_user_account_type_user_is_verify.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.7 on 2025-11-22 07:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='account_type', + field=models.CharField(choices=[('personal', 'Personal'), ('business', 'Business')], default='personal', max_length=255), + ), + migrations.AddField( + model_name='user', + name='is_verify', + field=models.BooleanField(default=False), + ), + ] diff --git a/core/apps/accounts/migrations/0003_address.py b/core/apps/accounts/migrations/0003_address.py new file mode 100644 index 0000000..dd85a0d --- /dev/null +++ b/core/apps/accounts/migrations/0003_address.py @@ -0,0 +1,30 @@ +# Generated by Django 5.2.7 on 2025-11-22 11:34 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0002_user_account_type_user_is_verify'), + ] + + operations = [ + migrations.CreateModel( + name='Address', + 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')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='addresses', to=settings.AUTH_USER_MODEL, verbose_name='User')), + ], + options={ + 'verbose_name': 'Address', + 'verbose_name_plural': 'Addresses', + 'db_table': 'address', + }, + ), + ] diff --git a/core/apps/accounts/migrations/0004_business_searchhistory.py b/core/apps/accounts/migrations/0004_business_searchhistory.py new file mode 100644 index 0000000..eb50c95 --- /dev/null +++ b/core/apps/accounts/migrations/0004_business_searchhistory.py @@ -0,0 +1,54 @@ +# Generated by Django 5.2.7 on 2025-11-24 06:45 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0003_address'), + ] + + operations = [ + migrations.CreateModel( + name='Business', + 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='Business Name')), + ('work_time', models.CharField(max_length=255, verbose_name='Work Time')), + ('contact', models.CharField(max_length=255, verbose_name='Contact')), + ('instagram', models.CharField(max_length=255, verbose_name='Instagram')), + ('facebook', models.CharField(max_length=255, verbose_name='Facebook')), + ('telegram', models.CharField(max_length=255, verbose_name='Telegram')), + ('bio', models.TextField(verbose_name='Bio')), + ('address_name', models.CharField(max_length=255, verbose_name='Address Name')), + ('longitude', models.FloatField(verbose_name='Longitude')), + ('latitude', models.FloatField(verbose_name='Latitude')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Business', + 'verbose_name_plural': 'Business', + 'db_table': 'business', + }, + ), + migrations.CreateModel( + name='SearchHistory', + 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)), + ('value', models.CharField(max_length=255, verbose_name='Search History')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User')), + ], + options={ + 'verbose_name': 'Search History', + 'verbose_name_plural': 'Search History', + 'db_table': 'search_history', + }, + ), + ] diff --git a/core/apps/accounts/models/__init__.py b/core/apps/accounts/models/__init__.py index bcfdb95..92bbf71 100644 --- a/core/apps/accounts/models/__init__.py +++ b/core/apps/accounts/models/__init__.py @@ -1,3 +1,7 @@ # isort: skip_file from .user import * # noqa from .reset_token import * # noqa +from .address import * # noqa +from .business import * # noqa +from .user_like import * # noqa +from .search_history import * # noqa diff --git a/core/apps/accounts/models/address.py b/core/apps/accounts/models/address.py new file mode 100644 index 0000000..9b31c36 --- /dev/null +++ b/core/apps/accounts/models/address.py @@ -0,0 +1,18 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model + + +class Address(AbstractBaseModel): + user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name='addresses', + verbose_name=_('User')) + name = models.CharField(max_length=255, verbose_name=_('Name')) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = 'address' + verbose_name = _('Address') + verbose_name_plural = _('Addresses') diff --git a/core/apps/accounts/models/business.py b/core/apps/accounts/models/business.py new file mode 100644 index 0000000..c4f27e7 --- /dev/null +++ b/core/apps/accounts/models/business.py @@ -0,0 +1,26 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model + + +class Business(AbstractBaseModel): + name = models.CharField(max_length=255, verbose_name=_('Business Name')) + user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE) + work_time = models.CharField(max_length=255, verbose_name=_('Work Time')) + contact = models.CharField(max_length=255, verbose_name=_('Contact')) + instagram = models.CharField(max_length=255, verbose_name=_('Instagram')) + facebook = models.CharField(max_length=255, verbose_name=_('Facebook')) + telegram = models.CharField(max_length=255, verbose_name=_('Telegram')) + bio = models.TextField(verbose_name=_('Bio')) + address_name = models.CharField(max_length=255, verbose_name=_('Address Name')) + longitude = models.FloatField(verbose_name=_('Longitude')) + latitude = models.FloatField(verbose_name=_('Latitude')) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = 'business' + verbose_name = _('Business') + verbose_name_plural = _('Business') diff --git a/core/apps/accounts/models/notification.py b/core/apps/accounts/models/notification.py new file mode 100644 index 0000000..6d696c4 --- /dev/null +++ b/core/apps/accounts/models/notification.py @@ -0,0 +1,35 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from core.apps.accounts.choices import NotificationType +from django.contrib.auth import get_user_model + + +class Notification(AbstractBaseModel): + title = models.CharField(max_length=255, verbose_name=_("Title")) + description = models.TextField(verbose_name=_("Description")) + notification_type = models.CharField(max_length=255, choices=NotificationType, verbose_name=_("Type")) + long = models.FloatField(verbose_name=_("Long")) + lat = models.FloatField(verbose_name=_("Lat")) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "notification" + verbose_name = _("Notification") + verbose_name_plural = _("Notifications") + + +class UserNotification(AbstractBaseModel): + user = models.ForeignKey(get_user_model(), verbose_name=_("User"), on_delete=models.CASCADE) + notification = models.ForeignKey(Notification, verbose_name=_("Notification"), on_delete=models.CASCADE) + is_read = models.BooleanField(verbose_name=_("Read"), default=False) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "user_notification" + verbose_name = _("User Notification") + verbose_name_plural = _("User Notifications") diff --git a/core/apps/accounts/models/search_history.py b/core/apps/accounts/models/search_history.py new file mode 100644 index 0000000..af218fa --- /dev/null +++ b/core/apps/accounts/models/search_history.py @@ -0,0 +1,17 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model + + +class SearchHistory(AbstractBaseModel): + value = models.CharField(verbose_name=_('Search History'), max_length=255) + user = models.ForeignKey(get_user_model(), verbose_name=_('User'), on_delete=models.CASCADE) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = 'search_history' + verbose_name = _('Search History') + verbose_name_plural = _('Search History') diff --git a/core/apps/accounts/models/user.py b/core/apps/accounts/models/user.py index d49fe0c..785a64f 100644 --- a/core/apps/accounts/models/user.py +++ b/core/apps/accounts/models/user.py @@ -1,7 +1,7 @@ from django.contrib.auth import models as auth_models from django.db import models -from ..choices import RoleChoice +from ..choices import RoleChoice, AccountType from ..managers import UserManager @@ -11,6 +11,8 @@ class User(auth_models.AbstractUser): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) validated_at = models.DateTimeField(null=True, blank=True) + is_verify = models.BooleanField(default=False) + account_type = models.CharField(choices=AccountType, max_length=255, default=AccountType.PERSONAL) role = models.CharField( max_length=255, choices=RoleChoice, diff --git a/core/apps/accounts/models/user_like.py b/core/apps/accounts/models/user_like.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/accounts/models/user_plan.py b/core/apps/accounts/models/user_plan.py new file mode 100644 index 0000000..a6ef1e8 --- /dev/null +++ b/core/apps/accounts/models/user_plan.py @@ -0,0 +1,31 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model + + +class Plan(AbstractBaseModel): + name = models.CharField(verbose_name=_("Name"), max_length=255) + price = models.DecimalField(verbose_name=_("Price"), max_digits=10, decimal_places=2) + + def __str__(self): + return str(self.id) + + class Meta: + db_table = "plan" + verbose_name = _("Plan") + verbose_name_plural = _("Plans") + + +class UserPlan(AbstractBaseModel): + user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, verbose_name=_("User")) + plan = models.ForeignKey(Plan, on_delete=models.CASCADE, verbose_name=_("Plan")) + expire = models.DateTimeField(verbose_name=_("Expire")) + + def __str__(self): + return str(self.id) + + class Meta: + db_table = "user_plan" + verbose_name = _("User Plan") + verbose_name_plural = _("User Plans") diff --git a/core/apps/api/__init__.py b/core/apps/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/api/admin/__init__.py b/core/apps/api/admin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/api/apps.py b/core/apps/api/apps.py new file mode 100644 index 0000000..02f0401 --- /dev/null +++ b/core/apps/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ModuleConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "core.apps.api" diff --git a/core/apps/api/choices/__init__.py b/core/apps/api/choices/__init__.py new file mode 100644 index 0000000..c71ca4f --- /dev/null +++ b/core/apps/api/choices/__init__.py @@ -0,0 +1,3 @@ +from .ad_type import * # noqa +from .ad_variant_type import * # noqa +from .order_status import * # noqa diff --git a/core/apps/api/choices/ad_type.py b/core/apps/api/choices/ad_type.py new file mode 100644 index 0000000..6b81883 --- /dev/null +++ b/core/apps/api/choices/ad_type.py @@ -0,0 +1,22 @@ +from django.utils.translation import gettext_lazy as _ +from django.db import models + + +class AdType(models.TextChoices): + """ + Ad type choices. + """ + + BUY = "Buy", _("Buy") + SELL = "Sell", _("Sell") + + +class AdCategoryType(models.TextChoices): + """ + Ad category type choices. + """ + + PRODUCT = "Product", _("Product") + SERVICE = "Service", _("Service") + AUTO = "Auto", _("Auto") + HOME = "Home", _("Home") diff --git a/core/apps/api/choices/ad_variant_type.py b/core/apps/api/choices/ad_variant_type.py new file mode 100644 index 0000000..7b0919a --- /dev/null +++ b/core/apps/api/choices/ad_variant_type.py @@ -0,0 +1,11 @@ +from django.utils.translation import gettext_lazy as _ +from django.db import models + + +class AdVariantType(models.TextChoices): + """ + Ad variant type choices. + """ + + COLOR = "Color", _("Color") + SIZE = "Size", _("Size") diff --git a/core/apps/api/choices/order_status.py b/core/apps/api/choices/order_status.py new file mode 100644 index 0000000..e3a9651 --- /dev/null +++ b/core/apps/api/choices/order_status.py @@ -0,0 +1,12 @@ +from django.utils.translation import gettext_lazy as _ +from django.db import models + + +class OrderStatus(models.TextChoices): + """ + Order Status choices. + """ + + PENDING = "Pending", _("Pending") + CANCEL = "Cancel", _("Cancel") + DONE = "Done", _("Done") diff --git a/core/apps/api/enums/__init__.py b/core/apps/api/enums/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/api/migrations/0001_initial.py b/core/apps/api/migrations/0001_initial.py new file mode 100644 index 0000000..837b5dd --- /dev/null +++ b/core/apps/api/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.7 on 2025-11-22 11:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Banner', + 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)), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('description', models.TextField(verbose_name='Description')), + ('mobile_image', models.ImageField(upload_to='banner/mobile_image/', verbose_name='Mobile Image')), + ('desktop_image', models.ImageField(upload_to='banner/desktop_image/', verbose_name='Desktop Image')), + ('link', models.URLField(verbose_name='Link')), + ('bg_color', models.CharField(max_length=255, verbose_name='BG Color')), + ('text_color', models.CharField(max_length=255, verbose_name='Text Color')), + ], + options={ + 'verbose_name': 'Banner', + 'verbose_name_plural': 'Banners', + 'db_table': 'banner', + }, + ), + ] diff --git a/core/apps/api/migrations/0002_adtopplan_color_tags_admodel_adimage_adoption_adsize_and_more.py b/core/apps/api/migrations/0002_adtopplan_color_tags_admodel_adimage_adoption_adsize_and_more.py new file mode 100644 index 0000000..22a739e --- /dev/null +++ b/core/apps/api/migrations/0002_adtopplan_color_tags_admodel_adimage_adoption_adsize_and_more.py @@ -0,0 +1,240 @@ +# Generated by Django 5.2.7 on 2025-11-24 06:45 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0004_business_searchhistory'), + ('api', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='AdTopPlan', + 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')), + ('price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Price')), + ('duration', models.IntegerField(verbose_name='Duration')), + ], + options={ + 'verbose_name': 'AdTop Plan', + 'verbose_name_plural': 'AdTop Plan', + 'db_table': 'ad_top_plan', + }, + ), + migrations.CreateModel( + name='Color', + 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': 'Color', + 'verbose_name_plural': 'Colors', + 'db_table': 'color', + }, + ), + migrations.CreateModel( + name='Tags', + 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': 'Tags', + 'verbose_name_plural': 'Tags', + 'db_table': 'tags', + }, + ), + migrations.CreateModel( + name='AdModel', + 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')), + ('ad_type', models.CharField(choices=[('Buy', 'Buy'), ('Sell', 'Sell')], max_length=255, verbose_name='Type')), + ('ad_category_type', models.CharField(choices=[('Product', 'Product'), ('Service', 'Service'), ('Auto', 'Auto'), ('Home', 'Home')], max_length=255, verbose_name='Type')), + ('price', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='Price')), + ('is_available', models.BooleanField(blank=True, default=True, null=True, verbose_name='Is available')), + ('physical_product', models.BooleanField(default=False, verbose_name='Physical product')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ad', to=settings.AUTH_USER_MODEL, verbose_name='User')), + ('plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.adtopplan', verbose_name='Plan')), + ], + options={ + 'verbose_name': 'Ad', + 'verbose_name_plural': 'Ads', + 'db_table': 'ad', + }, + ), + migrations.CreateModel( + name='AdImage', + 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)), + ('image', models.ImageField(upload_to='ads/images/', verbose_name='Image')), + ('ad', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.admodel', verbose_name='Ad')), + ], + options={ + 'verbose_name': 'Ad_Image', + 'verbose_name_plural': 'Ad_Images', + 'db_table': 'ad_images', + }, + ), + migrations.CreateModel( + name='AdOption', + 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')), + ('value', models.CharField(max_length=255, verbose_name='Value')), + ('ad', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.admodel')), + ], + options={ + 'verbose_name': 'Ad_Option', + 'verbose_name_plural': 'Ad_Options', + 'db_table': 'ad_option', + }, + ), + migrations.CreateModel( + name='AdSize', + 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)), + ('weight', models.PositiveIntegerField(verbose_name='Weight')), + ('width', models.PositiveIntegerField(verbose_name='Width')), + ('height', models.PositiveIntegerField(verbose_name='Height')), + ('length', models.PositiveIntegerField(verbose_name='Length')), + ('ad', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.admodel')), + ], + options={ + 'verbose_name': 'AdSize', + 'verbose_name_plural': 'AdSizes', + 'db_table': 'ad_size', + }, + ), + migrations.CreateModel( + name='AdVariant', + 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)), + ('variant', models.CharField(choices=[('Color', 'Color'), ('Size', 'Size')], db_index=True, max_length=255)), + ('value', models.CharField(max_length=255)), + ('is_available', models.CharField(max_length=255)), + ('price', models.DecimalField(decimal_places=2, max_digits=10)), + ('discount', models.DecimalField(decimal_places=2, default=-1, max_digits=10)), + ('ad', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.admodel')), + ], + options={ + 'verbose_name': 'Ad_Variant', + 'verbose_name_plural': 'Ad_Variants', + 'db_table': 'ad_variant', + }, + ), + migrations.CreateModel( + name='Category', + 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='Category Name')), + ('show_home', models.BooleanField(default=False, verbose_name='Show Home')), + ('level', models.IntegerField(default=0, verbose_name='Level')), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='api.category')), + ], + options={ + 'verbose_name': 'Category', + 'verbose_name_plural': 'Categories', + 'db_table': 'category', + }, + ), + migrations.AddField( + model_name='admodel', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.category', verbose_name='Category'), + ), + migrations.CreateModel( + name='Feedback', + 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)), + ('star', models.IntegerField(default=0, verbose_name='Star')), + ('command', models.CharField(max_length=255, verbose_name='Command')), + ('ad', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.admodel', verbose_name='Ad')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User')), + ], + options={ + 'verbose_name': 'Feedback', + 'verbose_name_plural': 'Feedbacks', + 'db_table': 'feedback', + }, + ), + migrations.CreateModel( + name='FeedbackImages', + 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)), + ('image', models.ImageField(upload_to='feedback/images/', verbose_name='Image')), + ('feedback', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.feedback', verbose_name='Feedback')), + ], + options={ + 'verbose_name': 'Feedback Images', + 'verbose_name_plural': 'Feedback Images', + 'db_table': 'feedback_images', + }, + ), + migrations.CreateModel( + name='Order', + 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)), + ('status', models.CharField(choices=[('Pending', 'Pending'), ('Cancel', 'Cancel'), ('Done', 'Done')], max_length=255)), + ('address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.address', verbose_name='Address')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User')), + ], + options={ + 'verbose_name': 'Order', + 'verbose_name_plural': 'Orders', + 'db_table': 'order', + }, + ), + migrations.CreateModel( + name='OrderItem', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Price')), + ('count', models.PositiveIntegerField(default=0, verbose_name='Count')), + ('ad', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.admodel', verbose_name='Ad')), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.order', verbose_name='Order')), + ], + options={ + 'verbose_name': 'Order Item', + 'verbose_name_plural': 'Order Items', + 'db_table': 'order_item', + }, + ), + migrations.AddField( + model_name='admodel', + name='tags', + field=models.ManyToManyField(to='api.tags', verbose_name='Tags'), + ), + ] diff --git a/core/apps/api/migrations/__init__.py b/core/apps/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/api/models/__init__.py b/core/apps/api/models/__init__.py new file mode 100644 index 0000000..c7d32cb --- /dev/null +++ b/core/apps/api/models/__init__.py @@ -0,0 +1,5 @@ +from .banner import * # noqa +from .feedback import * # noqa +from .ad import * # noqa +from .ad_items import * # noqa +from .order import * # noqa diff --git a/core/apps/api/models/ad/__init__.py b/core/apps/api/models/ad/__init__.py new file mode 100644 index 0000000..8c2d0b4 --- /dev/null +++ b/core/apps/api/models/ad/__init__.py @@ -0,0 +1,2 @@ +from .ad import * # noqa +from .category import * # noqa diff --git a/core/apps/api/models/ad/ad.py b/core/apps/api/models/ad/ad.py new file mode 100644 index 0000000..508c480 --- /dev/null +++ b/core/apps/api/models/ad/ad.py @@ -0,0 +1,38 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model +from core.apps.api.choices.ad_type import AdType, AdCategoryType + + +class AdModel(AbstractBaseModel): + user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, verbose_name=_("User"), related_name="ad") + name = models.CharField(verbose_name=_("Name"), max_length=255) + ad_type = models.CharField(verbose_name=_("Type"), max_length=255, choices=AdType) + category = models.ForeignKey("api.Category", on_delete=models.CASCADE, verbose_name=_("Category")) + ad_category_type = models.CharField(verbose_name=_("Type"), max_length=255, choices=AdCategoryType) + price = models.DecimalField(verbose_name=_("Price"), max_digits=10, decimal_places=2, null=True, blank=True) + is_available = models.BooleanField(verbose_name=_("Is available"), default=True, blank=True, null=True) + physical_product = models.BooleanField(verbose_name=_("Physical product"), default=False) + plan = models.ForeignKey("api.AdTopPlan", on_delete=models.CASCADE, verbose_name=_("Plan")) + tags = models.ManyToManyField("api.Tags", verbose_name=_("Tags")) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "ad" + verbose_name = _("Ad") + verbose_name_plural = _("Ads") + + +class Color(AbstractBaseModel): + name = models.CharField(verbose_name=_("Name"), max_length=255) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "color" + verbose_name = _("Color") + verbose_name_plural = _("Colors") diff --git a/core/apps/api/models/ad/category.py b/core/apps/api/models/ad/category.py new file mode 100644 index 0000000..5b6e560 --- /dev/null +++ b/core/apps/api/models/ad/category.py @@ -0,0 +1,18 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ + + +class Category(AbstractBaseModel): + name = models.CharField(max_length=255, verbose_name=_('Category Name')) + parent = models.ForeignKey('self', null=True, blank=True, related_name='children', on_delete=models.CASCADE) + show_home = models.BooleanField(default=False, verbose_name=_('Show Home')) + level = models.IntegerField(default=0, verbose_name=_('Level')) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = 'category' + verbose_name = _('Category') + verbose_name_plural = _('Categories') diff --git a/core/apps/api/models/ad_items/__init__.py b/core/apps/api/models/ad_items/__init__.py new file mode 100644 index 0000000..b44fb2d --- /dev/null +++ b/core/apps/api/models/ad_items/__init__.py @@ -0,0 +1,6 @@ +from .ad_top_plan import * # noqa +from .tags import * # noqa +from .ad_images import * # noqa +from .ad_option import * # noqa +from .ad_size import * # noqa +from .ad_variant import * # noqa diff --git a/core/apps/api/models/ad_items/ad_images.py b/core/apps/api/models/ad_items/ad_images.py new file mode 100644 index 0000000..c8bf117 --- /dev/null +++ b/core/apps/api/models/ad_items/ad_images.py @@ -0,0 +1,17 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from core.apps.api.models.ad.ad import AdModel + + +class AdImage(AbstractBaseModel): + image = models.ImageField(verbose_name=_("Image"), upload_to="ads/images/") + ad = models.ForeignKey(AdModel, verbose_name=_("Ad"), on_delete=models.CASCADE) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "ad_images" + verbose_name = _("Ad_Image") + verbose_name_plural = _("Ad_Images") diff --git a/core/apps/api/models/ad_items/ad_option.py b/core/apps/api/models/ad_items/ad_option.py new file mode 100644 index 0000000..11d54e5 --- /dev/null +++ b/core/apps/api/models/ad_items/ad_option.py @@ -0,0 +1,18 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from core.apps.api.models import AdModel + + +class AdOption(AbstractBaseModel): + name = models.CharField(_("Name"), max_length=255) + value = models.CharField(_("Value"), max_length=255) + ad = models.ForeignKey(AdModel, on_delete=models.CASCADE) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "ad_option" + verbose_name = _("Ad_Option") + verbose_name_plural = _("Ad_Options") diff --git a/core/apps/api/models/ad_items/ad_size.py b/core/apps/api/models/ad_items/ad_size.py new file mode 100644 index 0000000..8d8a1b2 --- /dev/null +++ b/core/apps/api/models/ad_items/ad_size.py @@ -0,0 +1,20 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from core.apps.api.models import AdModel + + +class AdSize(AbstractBaseModel): + ad = models.ForeignKey(AdModel, on_delete=models.CASCADE) + weight = models.PositiveIntegerField(verbose_name=_("Weight")) + width = models.PositiveIntegerField(verbose_name=_("Width")) + height = models.PositiveIntegerField(verbose_name=_("Height")) + length = models.PositiveIntegerField(verbose_name=_("Length")) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "ad_size" + verbose_name = _("AdSize") + verbose_name_plural = _("AdSizes") diff --git a/core/apps/api/models/ad_items/ad_top_plan.py b/core/apps/api/models/ad_items/ad_top_plan.py new file mode 100644 index 0000000..bfd4f3a --- /dev/null +++ b/core/apps/api/models/ad_items/ad_top_plan.py @@ -0,0 +1,16 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ + + +class AdTopPlan(AbstractBaseModel): + name = models.CharField(verbose_name=_('Name'), max_length=255) + price = models.DecimalField(verbose_name=_('Price'), max_digits=10, decimal_places=2) + duration = models.IntegerField(verbose_name=_('Duration')) + + def __str__(self): + return str(self.pk) + class Meta: + db_table = 'ad_top_plan' + verbose_name = _('AdTop Plan') + verbose_name_plural = _('AdTop Plan') diff --git a/core/apps/api/models/ad_items/ad_variant.py b/core/apps/api/models/ad_items/ad_variant.py new file mode 100644 index 0000000..28644d7 --- /dev/null +++ b/core/apps/api/models/ad_items/ad_variant.py @@ -0,0 +1,22 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from core.apps.api.models import AdModel +from core.apps.api.choices.ad_variant_type import AdVariantType + + +class AdVariant(AbstractBaseModel): + ad = models.ForeignKey(AdModel, on_delete=models.CASCADE) + variant = models.CharField(max_length=255, choices=AdVariantType, db_index=True) + value = models.CharField(max_length=255) + is_available = models.CharField(max_length=255) + price = models.DecimalField(max_digits=10, decimal_places=2) + discount = models.DecimalField(max_digits=10, decimal_places=2, default=-1) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "ad_variant" + verbose_name = _("Ad_Variant") + verbose_name_plural = _("Ad_Variants") diff --git a/core/apps/api/models/ad_items/tags.py b/core/apps/api/models/ad_items/tags.py new file mode 100644 index 0000000..f51285e --- /dev/null +++ b/core/apps/api/models/ad_items/tags.py @@ -0,0 +1,15 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ + + +class Tags(AbstractBaseModel): + name = models.CharField(verbose_name=_("Name"), max_length=255) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = 'tags' + verbose_name = _("Tags") + verbose_name_plural = _("Tags") diff --git a/core/apps/api/models/banner/__init__.py b/core/apps/api/models/banner/__init__.py new file mode 100644 index 0000000..1b144fd --- /dev/null +++ b/core/apps/api/models/banner/__init__.py @@ -0,0 +1 @@ +from .banner import * # noqa diff --git a/core/apps/api/models/banner/banner.py b/core/apps/api/models/banner/banner.py new file mode 100644 index 0000000..297d004 --- /dev/null +++ b/core/apps/api/models/banner/banner.py @@ -0,0 +1,21 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ +from django_core.models.base import AbstractBaseModel + + +class Banner(AbstractBaseModel): + title = models.CharField(max_length=255, verbose_name=_("Title")) + description = models.TextField(verbose_name=_("Description")) + mobile_image = models.ImageField(verbose_name=_("Mobile Image"), upload_to="banner/mobile_image/") + desktop_image = models.ImageField(verbose_name=_("Desktop Image"), upload_to="banner/desktop_image/") + link = models.URLField(verbose_name=_("Link")) + bg_color = models.CharField(verbose_name=_("BG Color"), max_length=255) + text_color = models.CharField(verbose_name=_("Text Color"), max_length=255) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "banner" + verbose_name = _("Banner") + verbose_name_plural = _("Banners") diff --git a/core/apps/api/models/feedback/__init__.py b/core/apps/api/models/feedback/__init__.py new file mode 100644 index 0000000..5e1a07c --- /dev/null +++ b/core/apps/api/models/feedback/__init__.py @@ -0,0 +1 @@ +from .feedback import * # noqa diff --git a/core/apps/api/models/feedback/feedback.py b/core/apps/api/models/feedback/feedback.py new file mode 100644 index 0000000..b54a5df --- /dev/null +++ b/core/apps/api/models/feedback/feedback.py @@ -0,0 +1,34 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model +from core.apps.api.models.ad import AdModel + + +class Feedback(AbstractBaseModel): + star = models.IntegerField(default=0, verbose_name=_("Star")) + user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, verbose_name=_("User")) + ad = models.ForeignKey(AdModel, on_delete=models.CASCADE, verbose_name=_("Ad")) + command = models.CharField(max_length=255, verbose_name=_("Command")) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "feedback" + verbose_name = _("Feedback") + verbose_name_plural = _("Feedbacks") + + +class FeedbackImages(AbstractBaseModel): + feedback = models.ForeignKey(Feedback, on_delete=models.CASCADE, verbose_name=_("Feedback")) + image = models.ImageField(verbose_name=_("Image"), upload_to="feedback/" + "images/") + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "feedback_images" + verbose_name = _("Feedback Images") + verbose_name_plural = _("Feedback Images") diff --git a/core/apps/api/models/order/__init__.py b/core/apps/api/models/order/__init__.py new file mode 100644 index 0000000..0747015 --- /dev/null +++ b/core/apps/api/models/order/__init__.py @@ -0,0 +1 @@ +from .order import * # noqa diff --git a/core/apps/api/models/order/order.py b/core/apps/api/models/order/order.py new file mode 100644 index 0000000..c2a8bb4 --- /dev/null +++ b/core/apps/api/models/order/order.py @@ -0,0 +1,36 @@ +from django.db import models +from django_core.models.base import AbstractBaseModel +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth import get_user_model +from core.apps.api.choices import OrderStatus +from core.apps.accounts.models import Address +from core.apps.api.models import AdModel + + +class Order(AbstractBaseModel): + user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, verbose_name=_("User")) + status = models.CharField(max_length=255, choices=OrderStatus) + address = models.ForeignKey(Address, on_delete=models.CASCADE, verbose_name=_("Address")) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "order" + verbose_name = _("Order") + verbose_name_plural = _("Orders") + + +class OrderItem(models.Model): + order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name=_("Order")) + price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("Price")) + ad = models.ForeignKey(AdModel, on_delete=models.CASCADE, verbose_name=_("Ad")) + count = models.PositiveIntegerField(default=0, verbose_name=_("Count")) + + def __str__(self): + return str(self.pk) + + class Meta: + db_table = "order_item" + verbose_name = _("Order Item") + verbose_name_plural = _("Order Items") diff --git a/core/apps/api/serializers/__init__.py b/core/apps/api/serializers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/api/tests/__init__.py b/core/apps/api/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/api/urls.py b/core/apps/api/urls.py new file mode 100644 index 0000000..5fa41be --- /dev/null +++ b/core/apps/api/urls.py @@ -0,0 +1,9 @@ +from django.urls import path, include +from rest_framework.routers import DefaultRouter + +router = DefaultRouter() + + +urlpatterns = [ + path("", include(router.urls)), +] diff --git a/core/apps/api/views/__init__.py b/core/apps/api/views/__init__.py new file mode 100644 index 0000000..e69de29