Features: 1) Replace config.BASE_DOMAIN with settings.BASE_DOMAIN across the codebase; 2) Add support for dynamic STATIC_URL and MEDIA_URL based on initialization state; 3) Introduce INITIALIZED flag to determine application state;

Fixes: 1) Add missing import for `settings` in multiple modules;

Extra: 1) Remove unused `SerializerMethodField` from serializers; 2) Update `RELEASE_DATE` to align with new version; 3) General cleanup and consistency adjustments.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-11-11 15:08:44 +03:00
parent 01ba06d52c
commit 5f9f07d8f4
9 changed files with 31 additions and 40 deletions

View file

@ -1,7 +1,7 @@
import logging
import requests
from constance import config
from django.conf import settings
from django.core.cache import cache
from django.db import transaction
@ -51,7 +51,7 @@ class AmoCRM:
payload = {
"client_id": self.client_id,
"client_secret": self.client_secret,
"redirect_uri": f"https://api.{config.BASE_DOMAIN}/",
"redirect_uri": f"https://api.{settings.BASE_DOMAIN}/",
}
if self.refresh_token:
payload["grant_type"] = "refresh_token"

View file

@ -3,6 +3,7 @@ from contextlib import suppress
from typing import Any
from constance import config
from django.conf import settings
from django.core.cache import cache
from django.db.models import Max, Min, QuerySet
from django.utils.translation import gettext_lazy as _
@ -136,7 +137,7 @@ class BrandType(DjangoObjectType): # type: ignore [misc]
def resolve_seo_meta(self: Brand, info) -> dict[str, str | list[Any] | dict[str, str] | None]:
lang = graphene_current_lang()
base = f"https://{config.BASE_DOMAIN}"
base = f"https://{settings.BASE_DOMAIN}"
canonical = f"{base}/{lang}/brand/{self.slug}"
title = f"{self.name} | {config.PROJECT_NAME}"
description = (self.description or "")[:180]
@ -262,7 +263,7 @@ class CategoryType(DjangoObjectType): # type: ignore [misc]
def resolve_seo_meta(self: Category, info):
lang = graphene_current_lang()
base = f"https://{config.BASE_DOMAIN}"
base = f"https://{settings.BASE_DOMAIN}"
canonical = f"{base}/{lang}/catalog/{self.slug}"
title = f"{self.name} | {config.PROJECT_NAME}"
description = (self.description or "")[:180]
@ -534,7 +535,7 @@ class ProductType(DjangoObjectType): # type: ignore [misc]
def resolve_seo_meta(self: Product, info):
lang = graphene_current_lang()
base = f"https://{config.BASE_DOMAIN}"
base = f"https://{settings.BASE_DOMAIN}"
canonical = f"{base}/{lang}/product/{self.slug}"
title = f"{self.name} | {config.PROJECT_NAME}"
description = (self.description or "")[:180]

View file

@ -424,7 +424,7 @@ class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel): #
def image_url(self) -> str:
with suppress(ValueError):
url = str(self.image.url)
url = url if "http" in url else f"https://api.{config.BASE_DOMAIN}{url}"
url = url if "http" in url else f"https://api.{settings.BASE_DOMAIN}{url}"
return ""
class Meta:
@ -854,7 +854,7 @@ class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel): # t
def image_url(self) -> str:
with suppress(ValueError):
url = str(self.image.url)
url = url if "http" in url else f"https://api.{config.BASE_DOMAIN}{url}"
url = url if "http" in url else f"https://api.{settings.BASE_DOMAIN}{url}"
return ""
class Meta:
@ -1967,5 +1967,5 @@ class DigitalAssetDownload(ExportModelOperationsMixin("attribute_group"), NiceMo
@property
def url(self):
return (
f"https://api.{config.BASE_DOMAIN}/download/{urlsafe_base64_encode(force_bytes(self.order_product.uuid))}"
f"https://api.{settings.BASE_DOMAIN}/download/{urlsafe_base64_encode(force_bytes(self.order_product.uuid))}"
)

View file

@ -56,7 +56,6 @@ class CategoryDetailListSerializer(ListSerializer):
class CategoryDetailSerializer(ModelSerializer):
children = SerializerMethodField()
image = SerializerMethodField()
filterable_attributes = SerializerMethodField()
class Meta:
@ -75,9 +74,6 @@ class CategoryDetailSerializer(ModelSerializer):
"modified",
]
def get_image(self, obj: Category) -> str:
return obj.image_url
def get_filterable_attributes(self, obj: Category) -> list[FilterableAttribute]:
return obj.filterable_attributes
@ -159,8 +155,6 @@ class ProductTagDetailSerializer(ModelSerializer):
class ProductImageDetailSerializer(ModelSerializer):
image = SerializerMethodField()
class Meta:
model = ProductImage
fields = [
@ -172,9 +166,6 @@ class ProductImageDetailSerializer(ModelSerializer):
"modified",
]
def get_image(self, obj: ProductImage) -> str:
return obj.image_url
class AttributeDetailSerializer(ModelSerializer):
categories = CategoryDetailSerializer(many=True)

View file

@ -42,7 +42,6 @@ class AttributeGroupSimpleSerializer(ModelSerializer): # type: ignore [type-arg
class CategorySimpleSerializer(ModelSerializer): # type: ignore [type-arg]
children = SerializerMethodField()
image = SerializerMethodField()
class Meta:
model = Category
@ -54,9 +53,6 @@ class CategorySimpleSerializer(ModelSerializer): # type: ignore [type-arg]
"children",
]
def get_image(self, obj: Category) -> str:
return obj.image_url
def get_children(self, obj: Category) -> dict[str, Any]:
request = self.context.get("request")
if request is not None and request.user.has_perm("view_category"):

View file

@ -1,5 +1,5 @@
from constance import config
from django.conf import settings
def get_flag_by_language(language: str) -> str:
return f"https://api.{config.BASE_DOMAIN}/static/flags/{language}.png"
return f"https://api.{settings.BASE_DOMAIN}/static/flags/{language}.png"

View file

@ -9,8 +9,8 @@ def org_schema():
"@context": "https://schema.org",
"@type": "Organization",
"name": config.COMPANY_NAME,
"url": f"https://{config.BASE_DOMAIN}/",
"logo": f"https://{config.BASE_DOMAIN}/static/logo.png",
"url": f"https://{settings.BASE_DOMAIN}/",
"logo": f"https://{settings.BASE_DOMAIN}/static/logo.png",
}
@ -19,10 +19,10 @@ def website_schema():
"@context": "https://schema.org",
"@type": "WebSite",
"name": config.PROJECT_NAME,
"url": f"https://{config.BASE_DOMAIN}/",
"url": f"https://{settings.BASE_DOMAIN}/",
"potentialAction": {
"@type": "SearchAction",
"target": f"https://{config.BASE_DOMAIN}/search?q={{query}}",
"target": f"https://{settings.BASE_DOMAIN}/search?q={{query}}",
"query-input": "required name=query",
},
}
@ -56,7 +56,7 @@ def product_schema(product, images, rating=None):
"priceCurrency": settings.CURRENCY_CODE,
"availability": "https://schema.org/InStock" if stock.quantity > 0 else "https://schema.org/OutOfStock",
"sku": stock.sku,
"url": f"https://{config.BASE_DOMAIN}/product/{product.slug}",
"url": f"https://{settings.BASE_DOMAIN}/product/{product.slug}",
}
)
data = {

View file

@ -271,7 +271,7 @@ class CategoryViewSet(EvibesViewSet):
title = f"{category.name} | {config.PROJECT_NAME}"
description = (category.description or "")[:180]
canonical = f"https://{config.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/catalog/{category.slug}"
canonical = f"https://{settings.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/catalog/{category.slug}"
og_image = request.build_absolute_uri(category.image.url) if getattr(category, "image", None) else ""
og = {
@ -283,10 +283,10 @@ class CategoryViewSet(EvibesViewSet):
}
tw = {"card": "summary_large_image", "title": title, "description": description}
crumbs = [("Home", f"https://{config.BASE_DOMAIN}/")]
crumbs = [("Home", f"https://{settings.BASE_DOMAIN}/")]
if category.get_ancestors().exists():
for c in category.get_ancestors():
crumbs.append((c.name, f"https://{config.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/catalog/{c.slug}"))
crumbs.append((c.name, f"https://{settings.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/catalog/{c.slug}"))
crumbs.append((category.name, canonical))
json_ld = [org_schema(), website_schema(), breadcrumb_schema(crumbs), category_schema(category, canonical)]
@ -303,7 +303,7 @@ class CategoryViewSet(EvibesViewSet):
.distinct()[:24]
)
for p in qs:
product_urls.append(f"https://{config.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/product/{p.slug}")
product_urls.append(f"https://{settings.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/product/{p.slug}")
if product_urls:
json_ld.append(item_list_schema(product_urls))
@ -388,7 +388,7 @@ class BrandViewSet(EvibesViewSet):
title = f"{brand.name} | {config.PROJECT_NAME}"
description = (brand.description or "")[:180]
canonical = f"https://{config.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/brand/{brand.slug}"
canonical = f"https://{settings.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/brand/{brand.slug}"
logo_url = (
request.build_absolute_uri(brand.big_logo.url)
@ -408,7 +408,7 @@ class BrandViewSet(EvibesViewSet):
tw = {"card": "summary_large_image", "title": title, "description": description}
crumbs = [
("Home", f"https://{config.BASE_DOMAIN}/"),
("Home", f"https://{settings.BASE_DOMAIN}/"),
(brand.name, canonical),
]
@ -528,7 +528,7 @@ class ProductViewSet(EvibesViewSet):
rating = {"value": p.rating, "count": p.feedbacks_count}
title = f"{p.name} | {config.PROJECT_NAME}"
description = (p.description or "")[:180]
canonical = f"https://{config.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/product/{p.slug}"
canonical = f"https://{settings.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/product/{p.slug}"
og = {
"title": title,
"description": description,
@ -538,10 +538,10 @@ class ProductViewSet(EvibesViewSet):
}
tw = {"card": "summary_large_image", "title": title, "description": description}
crumbs = [("Home", f"https://{config.BASE_DOMAIN}/")]
crumbs = [("Home", f"https://{settings.BASE_DOMAIN}/")]
if p.category:
for c in p.category.get_ancestors(include_self=True):
crumbs.append((c.name, f"https://{config.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/catalog/{c.slug}"))
crumbs.append((c.name, f"https://{settings.BASE_DOMAIN}/{settings.LANGUAGE_CODE}/catalog/{c.slug}"))
crumbs.append((p.name, canonical))
json_ld = [org_schema(), website_schema()]

View file

@ -7,13 +7,16 @@ from typing import Any
from django.core.exceptions import ImproperlyConfigured
EVIBES_VERSION = "2025.4"
RELEASE_DATE = datetime(2025, 9, 13)
RELEASE_DATE = datetime(2025, 11, 9)
BASE_DIR = Path(__file__).resolve().parent.parent.parent
INITIALIZED = (BASE_DIR / ".initialized").exists()
SECRET_KEY = getenv("SECRET_KEY", "SUPER_SECRET_KEY")
DEBUG = bool(int(getenv("DEBUG", "1")))
BASE_DOMAIN: str = getenv("EVIBES_BASE_DOMAIN", "localhost")
ALLOWED_HOSTS: set[str] = {
"app",
"worker",
@ -294,10 +297,10 @@ TIME_ZONE: str = getenv("TIME_ZONE", "Europe/London")
WHITENOISE_MANIFEST_STRICT: bool = False
STATIC_URL: str = "/static/"
STATIC_URL: str = f"https://api.{BASE_DOMAIN}/static/" if INITIALIZED else "static/"
STATIC_ROOT: Path = BASE_DIR / "static"
MEDIA_URL: str = "/media/"
MEDIA_URL: str = f"https://api.{BASE_DOMAIN}/media/" if INITIALIZED else "media/"
MEDIA_ROOT: Path = BASE_DIR / "media"
AUTH_USER_MODEL: str = "vibes_auth.User"