feat(category): add brands relationship and resolve method
enable brands association with categories and allow querying of active brands within a category. Updated GraphQL schema, models, and serializers to include this relationship while deprecating redundant category-to-brand ManyToManyField.
This commit is contained in:
parent
10f5c798d4
commit
87ed875fe6
4 changed files with 19 additions and 6 deletions
|
|
@ -421,10 +421,7 @@ class BrandAdmin(
|
|||
"priority",
|
||||
"is_active",
|
||||
)
|
||||
list_filter = (
|
||||
"categories",
|
||||
"is_active",
|
||||
)
|
||||
list_filter = ("is_active",)
|
||||
search_fields = (
|
||||
"uuid",
|
||||
"name",
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ class CategoryType(DjangoObjectType):
|
|||
"minimum and maximum prices for products in this category, if available."
|
||||
),
|
||||
)
|
||||
brands = List(lambda: BrandType, description=_("brands in this category"))
|
||||
tags = DjangoFilterConnectionField(
|
||||
lambda: CategoryTagType, description=_("tags for this category")
|
||||
)
|
||||
|
|
@ -249,6 +250,7 @@ class CategoryType(DjangoObjectType):
|
|||
"slug",
|
||||
"description",
|
||||
"image",
|
||||
"brands",
|
||||
"min_max_prices",
|
||||
)
|
||||
filter_fields = ["uuid"]
|
||||
|
|
@ -294,6 +296,9 @@ class CategoryType(DjangoObjectType):
|
|||
"max_price": min_max_prices["max_price"],
|
||||
}
|
||||
|
||||
def resolve_brands(self: Category, info) -> QuerySet[Brand]:
|
||||
return self.brands
|
||||
|
||||
def resolve_seo_meta(self: Category, info):
|
||||
lang = graphene_current_lang()
|
||||
base = f"https://{settings.BASE_DOMAIN}"
|
||||
|
|
|
|||
|
|
@ -443,6 +443,14 @@ class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel):
|
|||
# Fallback to favicon.png from static files
|
||||
return static("favicon.png")
|
||||
|
||||
@cached_property
|
||||
def brands(self) -> QuerySet["Brand"]:
|
||||
return Brand.objects.filter(
|
||||
products__category=self,
|
||||
products__is_active=True,
|
||||
is_active=True,
|
||||
).distinct()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("category")
|
||||
verbose_name_plural = _("categories")
|
||||
|
|
@ -490,8 +498,8 @@ class Brand(ExportModelOperationsMixin("brand"), NiceModel):
|
|||
categories = ManyToManyField(
|
||||
"core.Category",
|
||||
blank=True,
|
||||
help_text=_("optional categories that this brand is associated with"),
|
||||
verbose_name=_("associated categories"),
|
||||
help_text=_("DEPRECATED"),
|
||||
verbose_name=_("DEPRECATED"),
|
||||
)
|
||||
slug = AutoSlugField(
|
||||
populate_from=("name",),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from engine.core.models import (
|
|||
Wishlist,
|
||||
)
|
||||
from engine.core.serializers.simple import (
|
||||
BrandSimpleSerializer,
|
||||
CategorySimpleSerializer,
|
||||
ProductSimpleSerializer,
|
||||
)
|
||||
|
|
@ -60,6 +61,7 @@ class CategoryDetailListSerializer(ListSerializer):
|
|||
class CategoryDetailSerializer(ModelSerializer):
|
||||
children = SerializerMethodField()
|
||||
filterable_attributes = SerializerMethodField()
|
||||
brands = BrandSimpleSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Category
|
||||
|
|
@ -71,6 +73,7 @@ class CategoryDetailSerializer(ModelSerializer):
|
|||
"image",
|
||||
"markup_percent",
|
||||
"filterable_attributes",
|
||||
"brands",
|
||||
"children",
|
||||
"slug",
|
||||
"created",
|
||||
|
|
|
|||
Loading…
Reference in a new issue