Features: 1) Add Stock existence filters for has_price and has_stock annotations in queries; 2) Introduce personal_order_tail for improved ordering logic; 3) Support advanced filtering in DjangoFilterConnectionField with augmented filters and types.
Fixes: 1) Correct import order in multiple files; 2) Remove unnecessary migration file metadata changes. Extra: 1) Refactor ordering logic to streamline query annotations; 2) Improve code readability with explicit list annotations and consistent formatting adjustments.
This commit is contained in:
parent
0752221d22
commit
f646d5ab09
3 changed files with 39 additions and 49 deletions
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
|||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("blog", "0005_post_content_fa_ir_post_content_he_il_and_more"),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import uuid
|
|||
from django.core.exceptions import BadRequest
|
||||
from django.db.models import (
|
||||
Avg,
|
||||
BooleanField,
|
||||
Case,
|
||||
Exists,
|
||||
FloatField,
|
||||
IntegerField,
|
||||
Max,
|
||||
OuterRef,
|
||||
Prefetch,
|
||||
|
|
@ -33,7 +33,7 @@ from django_filters import (
|
|||
)
|
||||
|
||||
from core.elasticsearch import process_query
|
||||
from core.models import Address, Brand, Category, Feedback, Order, Product, Wishlist
|
||||
from core.models import Address, Brand, Category, Feedback, Order, Product, Stock, Wishlist
|
||||
|
||||
logger = logging.getLogger("django")
|
||||
|
||||
|
|
@ -276,41 +276,43 @@ class ProductFilter(FilterSet):
|
|||
|
||||
ordering_param = self.data.get("order_by", "")
|
||||
|
||||
stock_with_price = Stock.objects.filter(product_uuid=OuterRef("pk"), price__gt=0)
|
||||
stock_with_qty = Stock.objects.filter(product_uuid=OuterRef("pk"), quantity__gt=0)
|
||||
|
||||
qs = qs.annotate(
|
||||
has_stock=Case(
|
||||
When(stocks__quantity__gt=0, then=Value(True)),
|
||||
default=Value(False),
|
||||
output_field=BooleanField(),
|
||||
),
|
||||
has_price=Case(
|
||||
When(stocks__price__gt=0, then=Value(True)),
|
||||
default=Value(False),
|
||||
output_field=BooleanField(),
|
||||
),
|
||||
has_price=Exists(stock_with_price),
|
||||
has_stock=Exists(stock_with_qty),
|
||||
).annotate(
|
||||
personal_orders_only=Case(
|
||||
When(has_stock=False, has_price=False, then=Value(True)),
|
||||
default=Value(False),
|
||||
output_field=BooleanField(),
|
||||
personal_order_tail=Case(
|
||||
When(Q(has_price=False) | Q(has_stock=False), then=Value(1)),
|
||||
default=Value(0),
|
||||
output_field=IntegerField(),
|
||||
)
|
||||
)
|
||||
|
||||
requested = [part.strip() for part in ordering_param.split(",") if part.strip()] if ordering_param else []
|
||||
mapped_requested = []
|
||||
mapped_requested: list[str] = []
|
||||
|
||||
for part in requested:
|
||||
desc = part.startswith("-")
|
||||
key = part.lstrip("-")
|
||||
|
||||
if key == "price":
|
||||
key = "price_order"
|
||||
|
||||
if key == "random":
|
||||
key = "?"
|
||||
mapped_requested.append(key)
|
||||
mapped_requested.append("?")
|
||||
continue
|
||||
if key == "personal_orders_only":
|
||||
|
||||
if key in {"personal_orders_only", "personal_order_only", "personal_order_tail"}:
|
||||
continue
|
||||
|
||||
mapped_requested.append(f"-{key}" if desc else key)
|
||||
|
||||
final_ordering = mapped_requested + ["personal_orders_only"]
|
||||
if "?" in mapped_requested:
|
||||
final_ordering = ["personal_order_tail", "?"]
|
||||
else:
|
||||
final_ordering = mapped_requested + ["personal_order_tail"]
|
||||
|
||||
if final_ordering:
|
||||
qs = qs.order_by(*final_ordering)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
import logging
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db.models import Max, Case, When, Value, IntegerField, BooleanField
|
||||
from django.utils import timezone
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import Case, Exists, IntegerField, OuterRef, Q, Value, When
|
||||
from django.utils import timezone
|
||||
from graphene import Field, List, ObjectType, Schema
|
||||
from graphene_django.filter import DjangoFilterConnectionField
|
||||
|
||||
from blog.filters import PostFilter
|
||||
from blog.graphene.object_types import PostType
|
||||
from core.filters import (
|
||||
AddressFilter,
|
||||
BrandFilter,
|
||||
CategoryFilter,
|
||||
FeedbackFilter,
|
||||
OrderFilter,
|
||||
ProductFilter,
|
||||
WishlistFilter,
|
||||
AddressFilter,
|
||||
)
|
||||
from core.graphene.mutations import (
|
||||
AddOrderProduct,
|
||||
|
|
@ -44,6 +44,7 @@ from core.graphene.mutations import (
|
|||
UpdateProduct,
|
||||
)
|
||||
from core.graphene.object_types import (
|
||||
AddressType,
|
||||
AttributeGroupType,
|
||||
BrandType,
|
||||
CategoryTagType,
|
||||
|
|
@ -61,9 +62,9 @@ from core.graphene.object_types import (
|
|||
StockType,
|
||||
VendorType,
|
||||
WishlistType,
|
||||
AddressType,
|
||||
)
|
||||
from core.models import (
|
||||
Address,
|
||||
AttributeGroup,
|
||||
Brand,
|
||||
Category,
|
||||
|
|
@ -79,7 +80,6 @@ from core.models import (
|
|||
Stock,
|
||||
Vendor,
|
||||
Wishlist,
|
||||
Address,
|
||||
)
|
||||
from core.utils import get_project_parameters
|
||||
from core.utils.languages import get_flag_by_language
|
||||
|
|
@ -163,35 +163,24 @@ class Query(ObjectType):
|
|||
.prefetch_related("images", "stocks")
|
||||
)
|
||||
|
||||
base_qs = (
|
||||
stock_with_price = Stock.objects.filter(product_uuid=OuterRef("pk"), price__gt=0)
|
||||
stock_with_qty = Stock.objects.filter(product_uuid=OuterRef("pk"), quantity__gt=0)
|
||||
|
||||
return (
|
||||
base_qs.annotate(
|
||||
has_stock=Max(
|
||||
Case(
|
||||
When(stocks__quantity__gt=0, then=Value(1)),
|
||||
default=Value(0),
|
||||
output_field=IntegerField(),
|
||||
)
|
||||
),
|
||||
has_price=Max(
|
||||
Case(
|
||||
When(stocks__price__gt=0, then=Value(1)),
|
||||
default=Value(0),
|
||||
output_field=IntegerField(),
|
||||
)
|
||||
),
|
||||
has_price=Exists(stock_with_price),
|
||||
has_stock=Exists(stock_with_qty),
|
||||
)
|
||||
.annotate(
|
||||
personal_order_only=Case(
|
||||
When(has_stock=0, has_price=1, then=Value(True)),
|
||||
default=Value(False),
|
||||
output_field=BooleanField(),
|
||||
personal_order_tail=Case(
|
||||
When(Q(has_price=False) | Q(has_stock=False), then=Value(1)),
|
||||
default=Value(0),
|
||||
output_field=IntegerField(),
|
||||
)
|
||||
)
|
||||
.order_by("personal_order_only")
|
||||
.order_by("personal_order_tail")
|
||||
)
|
||||
|
||||
return base_qs
|
||||
|
||||
@staticmethod
|
||||
def resolve_orders(_parent, info, **kwargs):
|
||||
orders = Order.objects
|
||||
|
|
|
|||
Loading…
Reference in a new issue