Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

queryset.py 2.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from django.db import models
  2. from oscar.core.loading import get_class
  3. ExpandUpwardsCategoryQueryset = get_class("catalogue.expressions", "ExpandUpwardsCategoryQueryset")
  4. class RangeQuerySet(models.query.QuerySet):
  5. """
  6. This queryset add ``contains_product`` which allows selecting the
  7. ranges that contain the product in question.
  8. """
  9. def _excluded_products_clause(self, product):
  10. if product.structure == product.CHILD:
  11. # child products are excluded from a range if either they are
  12. # excluded, or their parent.
  13. return ~(
  14. models.Q(excluded_products=product)
  15. | models.Q(excluded_products__id=product.parent_id)
  16. )
  17. return ~models.Q(excluded_products=product)
  18. def _included_products_clause(self, product):
  19. if product.structure == product.CHILD:
  20. # child products are included in a range if either they are
  21. # included, or their parent is included
  22. return models.Q(included_products=product) | models.Q(
  23. included_products__id=product.parent_id
  24. )
  25. else:
  26. return models.Q(included_products=product)
  27. def _productclasses_clause(self, product):
  28. if product.structure == product.CHILD:
  29. # child products are included in a range if their parent is
  30. # included in the range by means of their productclass.
  31. return models.Q(classes__products__parent_id=product.parent_id)
  32. return models.Q(classes__id=product.product_class_id)
  33. def _get_category_ids(self, product):
  34. if product.structure == product.CHILD:
  35. # Since a child can not be in a catagory, it must be determined
  36. # which category the parent is in
  37. ProductCategory = product.productcategory_set.model
  38. return ProductCategory.objects.filter(product_id=product.parent_id).values("category_id")
  39. return product.categories.values("id")
  40. def contains_product(self, product):
  41. # the wide query is used to determine which ranges have includes_all_products
  42. # turned on, we only need to look at explicit exclusions, the other
  43. # mechanism for adding a product to a range don't need to be checked
  44. wide = self.filter(
  45. self._excluded_products_clause(product), includes_all_products=True
  46. )
  47. narrow = self.filter(
  48. self._excluded_products_clause(product),
  49. self._included_products_clause(product)
  50. | models.Q(included_categories__in=ExpandUpwardsCategoryQueryset(self._get_category_ids(product)))
  51. | self._productclasses_clause(product),
  52. includes_all_products=False,
  53. )
  54. return wide | narrow