Features: 1) Replace IntegerField with BooleanField for has_stock, has_price, and personal_orders_only annotations; 2) Modify final ordering logic to append personal_orders_only at the end.

Fixes: 1) Handle missing `download` relation in `download_url` method by creating a new `DigitalAssetDownload` instance.

Extra: 1) Rename `personal_order_only` to `personal_orders_only` for clarity; 2) Remove unused IntegerField import; 3) General cleanup and minor adjustments in filters logic.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-10-03 16:56:29 +03:00
parent 63b3a93938
commit d917584829
2 changed files with 14 additions and 12 deletions

View file

@ -9,7 +9,6 @@ from django.db.models import (
Case,
Exists,
FloatField,
IntegerField,
Max,
OuterRef,
Prefetch,
@ -280,21 +279,21 @@ class ProductFilter(FilterSet):
qs = qs.annotate(
has_stock=Max(
Case(
When(stocks__quantity__gt=0, then=Value(1)),
default=Value(0),
output_field=IntegerField(),
When(stocks__quantity__gt=0, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
),
has_price=Max(
Case(
When(stocks__price__gt=0, then=Value(1)),
default=Value(0),
output_field=IntegerField(),
When(stocks__price__gt=0, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
),
).annotate(
personal_order_only=Case(
When(has_stock=0, has_price=1, then=Value(True)),
personal_orders_only=Case(
When(has_stock=False, has_price=False, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
@ -311,11 +310,11 @@ class ProductFilter(FilterSet):
key = "?"
mapped_requested.append(key)
continue
if key == "personal_order_only":
if key == "personal_orders_only":
continue
mapped_requested.append(f"-{key}" if desc else key)
final_ordering = ["personal_order_only"] + mapped_requested
final_ordering = mapped_requested + ["personal_orders_only"]
if final_ordering:
qs = qs.order_by(*final_ordering)

View file

@ -1780,7 +1780,10 @@ class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel): # t
def download_url(self: Self) -> str:
if self.product and self.product.stocks:
if self.product.is_digital and self.product.stocks.first().digital_asset: # type: ignore [union-attr]
return self.download.url
try:
return self.download.url
except self.download.RelatedObjectDoesNotExist:
return DigitalAssetDownload.objects.create(order_product=self).url
return ""
def do_feedback(self, rating=10, comment="", action="add") -> Optional["Feedback"] | int: