Features: 1) Ensure querysets return distinct results in filters;
Fixes: 1) Address potential duplication issue in querysets; Extra:
This commit is contained in:
parent
d40d7d3c28
commit
d72c3947d4
1 changed files with 86 additions and 24 deletions
110
core/filters.py
110
core/filters.py
|
|
@ -48,19 +48,31 @@ class CaseInsensitiveListFilter(BaseInFilter, CharFilter):
|
|||
class ProductFilter(FilterSet):
|
||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
|
||||
name = CharFilter(field_name="name", lookup_expr="icontains", label=_("Name"))
|
||||
categories = CaseInsensitiveListFilter(field_name="category__name", label=_("Categories"))
|
||||
categories = CaseInsensitiveListFilter(
|
||||
field_name="category__name", label=_("Categories")
|
||||
)
|
||||
category_uuid = CharFilter(method="filter_category", label="Category (UUID)")
|
||||
categories_slugs = CaseInsensitiveListFilter(field_name="category__slug", label=_("Categories Slugs"))
|
||||
categories_slugs = CaseInsensitiveListFilter(
|
||||
field_name="category__slug", label=_("Categories Slugs")
|
||||
)
|
||||
tags = CaseInsensitiveListFilter(field_name="tags__tag_name", label=_("Tags"))
|
||||
min_price = NumberFilter(field_name="stocks__price", lookup_expr="gte", label=_("Min Price"))
|
||||
max_price = NumberFilter(field_name="stocks__price", lookup_expr="lte", label=_("Max Price"))
|
||||
min_price = NumberFilter(
|
||||
field_name="stocks__price", lookup_expr="gte", label=_("Min Price")
|
||||
)
|
||||
max_price = NumberFilter(
|
||||
field_name="stocks__price", lookup_expr="lte", label=_("Max Price")
|
||||
)
|
||||
is_active = BooleanFilter(field_name="is_active", label=_("Is Active"))
|
||||
brand = CharFilter(field_name="brand__name", lookup_expr="iexact", label=_("Brand"))
|
||||
attributes = CharFilter(method="filter_attributes", label=_("Attributes"))
|
||||
quantity = NumberFilter(field_name="stocks__quantity", lookup_expr="gt", label=_("Quantity"))
|
||||
quantity = NumberFilter(
|
||||
field_name="stocks__quantity", lookup_expr="gt", label=_("Quantity")
|
||||
)
|
||||
slug = CharFilter(field_name="slug", lookup_expr="exact", label=_("Slug"))
|
||||
is_digital = BooleanFilter(field_name="is_digital", label=_("Is Digital"))
|
||||
include_subcategories = BooleanFilter(method="filter_include_flag", label=_("Include sub-categories"))
|
||||
include_subcategories = BooleanFilter(
|
||||
method="filter_include_flag", label=_("Include sub-categories")
|
||||
)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
|
|
@ -111,13 +123,16 @@ class ProductFilter(FilterSet):
|
|||
)
|
||||
self.queryset = self.queryset.annotate(
|
||||
rating=Coalesce(
|
||||
Subquery(feedback_qs, output_field=FloatField()), Value(0, output_field=FloatField())
|
||||
Subquery(feedback_qs, output_field=FloatField()),
|
||||
Value(0, output_field=FloatField()),
|
||||
)
|
||||
)
|
||||
|
||||
def filter_include_flag(self, queryset, **_kwargs):
|
||||
if not self.data.get("category_uuid"):
|
||||
raise BadRequest(_("there must be a category_uuid to use include_subcategories flag"))
|
||||
raise BadRequest(
|
||||
_("there must be a category_uuid to use include_subcategories flag")
|
||||
)
|
||||
return queryset
|
||||
|
||||
def filter_attributes(self, queryset, _name, value):
|
||||
|
|
@ -240,7 +255,8 @@ class ProductFilter(FilterSet):
|
|||
)
|
||||
qs = qs.annotate(
|
||||
rating=Coalesce(
|
||||
Subquery(feedback_qs, output_field=FloatField()), Value(0, output_field=FloatField())
|
||||
Subquery(feedback_qs, output_field=FloatField()),
|
||||
Value(0, output_field=FloatField()),
|
||||
)
|
||||
)
|
||||
return qs.distinct()
|
||||
|
|
@ -252,14 +268,26 @@ class OrderFilter(FilterSet):
|
|||
label=_("Search (ID, product name or part number)"),
|
||||
)
|
||||
|
||||
min_buy_time = DateTimeFilter(field_name="buy_time", lookup_expr="gte", label=_("Bought after (inclusive)"))
|
||||
max_buy_time = DateTimeFilter(field_name="buy_time", lookup_expr="lte", label=_("Bought before (inclusive)"))
|
||||
min_buy_time = DateTimeFilter(
|
||||
field_name="buy_time", lookup_expr="gte", label=_("Bought after (inclusive)")
|
||||
)
|
||||
max_buy_time = DateTimeFilter(
|
||||
field_name="buy_time", lookup_expr="lte", label=_("Bought before (inclusive)")
|
||||
)
|
||||
|
||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
||||
user_email = CharFilter(field_name="user__email", lookup_expr="iexact", label=_("User email"))
|
||||
user = UUIDFilter(field_name="user__uuid", lookup_expr="exact", label=_("User UUID"))
|
||||
user_email = CharFilter(
|
||||
field_name="user__email", lookup_expr="iexact", label=_("User email")
|
||||
)
|
||||
user = UUIDFilter(
|
||||
field_name="user__uuid", lookup_expr="exact", label=_("User UUID")
|
||||
)
|
||||
status = CharFilter(field_name="status", lookup_expr="icontains", label=_("Status"))
|
||||
human_readable_id = CharFilter(field_name="human_readable_id", lookup_expr="exact", label=_("Human Readable ID"))
|
||||
human_readable_id = CharFilter(
|
||||
field_name="human_readable_id",
|
||||
lookup_expr="exact",
|
||||
label=_("Human Readable ID"),
|
||||
)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
|
|
@ -299,11 +327,20 @@ class OrderFilter(FilterSet):
|
|||
|
||||
class WishlistFilter(FilterSet):
|
||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
||||
user_email = CharFilter(field_name="user__email", lookup_expr="iexact", label=_("User email"))
|
||||
user = UUIDFilter(field_name="user__uuid", lookup_expr="exact", label=_("User UUID"))
|
||||
user_email = CharFilter(
|
||||
field_name="user__email", lookup_expr="iexact", label=_("User email")
|
||||
)
|
||||
user = UUIDFilter(
|
||||
field_name="user__uuid", lookup_expr="exact", label=_("User UUID")
|
||||
)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(("uuid", "uuid"), ("created", "created"), ("modified", "modified"), ("?", "random"))
|
||||
fields=(
|
||||
("uuid", "uuid"),
|
||||
("created", "created"),
|
||||
("modified", "modified"),
|
||||
("?", "random"),
|
||||
)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
|
@ -317,7 +354,9 @@ class CategoryFilter(FilterSet):
|
|||
parent_uuid = CharFilter(method="filter_parent_uuid", label=_("Parent"))
|
||||
slug = CharFilter(field_name="slug", lookup_expr="exact", label=_("Slug"))
|
||||
whole = BooleanFilter(
|
||||
field_name="whole", label=_("Whole category(has at least 1 product or not)"), method="filter_whole_categories"
|
||||
field_name="whole",
|
||||
label=_("Whole category(has at least 1 product or not)"),
|
||||
method="filter_whole_categories",
|
||||
)
|
||||
tags = CaseInsensitiveListFilter(field_name="tags__tag_name", label=_("Tags"))
|
||||
level = NumberFilter(field_name="level", lookup_expr="exact", label=_("Level"))
|
||||
|
|
@ -332,7 +371,16 @@ class CategoryFilter(FilterSet):
|
|||
|
||||
class Meta:
|
||||
model = Category
|
||||
fields = ["uuid", "name", "parent_uuid", "slug", "tags", "level", "order_by", "whole"]
|
||||
fields = [
|
||||
"uuid",
|
||||
"name",
|
||||
"parent_uuid",
|
||||
"slug",
|
||||
"tags",
|
||||
"level",
|
||||
"order_by",
|
||||
"whole",
|
||||
]
|
||||
|
||||
def filter_whole_categories(self, queryset, _name, value):
|
||||
has_own_products = Exists(Product.objects.filter(category=OuterRef("pk")))
|
||||
|
|
@ -364,7 +412,9 @@ class CategoryFilter(FilterSet):
|
|||
class BrandFilter(FilterSet):
|
||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
||||
name = CharFilter(field_name="name", lookup_expr="icontains", label=_("Name"))
|
||||
categories = CaseInsensitiveListFilter(field_name="categories__uuid", lookup_expr="exact", label=_("Categories"))
|
||||
categories = CaseInsensitiveListFilter(
|
||||
field_name="categories__uuid", lookup_expr="exact", label=_("Categories")
|
||||
)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
|
|
@ -381,8 +431,16 @@ class BrandFilter(FilterSet):
|
|||
|
||||
class FeedbackFilter(FilterSet):
|
||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
|
||||
product_uuid = UUIDFilter(field_name="order_product__product__uuid", lookup_expr="exact", label=_("Product UUID"))
|
||||
user_uuid = UUIDFilter(field_name="order_product__order__user__uuid", lookup_expr="exact", label=_("User UUID"))
|
||||
product_uuid = UUIDFilter(
|
||||
field_name="order_product__product__uuid",
|
||||
lookup_expr="exact",
|
||||
label=_("Product UUID"),
|
||||
)
|
||||
user_uuid = UUIDFilter(
|
||||
field_name="order_product__order__user__uuid",
|
||||
lookup_expr="exact",
|
||||
label=_("User UUID"),
|
||||
)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
|
|
@ -402,8 +460,12 @@ class FeedbackFilter(FilterSet):
|
|||
|
||||
class AddressFilter(FilterSet):
|
||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
|
||||
user_uuid = UUIDFilter(field_name="user__uuid", lookup_expr="exact", label=_("User UUID"))
|
||||
user_email = CharFilter(field_name="user__email", lookup_expr="iexact", label=_("User email"))
|
||||
user_uuid = UUIDFilter(
|
||||
field_name="user__uuid", lookup_expr="exact", label=_("User UUID")
|
||||
)
|
||||
user_email = CharFilter(
|
||||
field_name="user__email", lookup_expr="iexact", label=_("User email")
|
||||
)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
|
|
|
|||
Loading…
Reference in a new issue