У меня есть модель ProductFilter
в проекте. Объект этой модели - это набор поисков, определяющих набор запросов. Это как группа товаров - но как фильтр, не связанный с ForeignKey (ManyToManyField).
Товар может быть отфильтрован за несколько ProductFilter
с, и первый учитывается.
Это работает так:
Пользователь определяет свои фильтры. Затем назначьте каждому фильтру некоторые правила ценообразования (и другие). Например, фильтр с именем «Продукты до 10 долларов США» - правило - увеличивает цену на 10% .
Проблема заключается в том, что при рендеринге продуктов или экспорте их. Я должен проверить для каждого продукта, принадлежат ли они к какому-либо фильтру, что означает много запросов к БД. Может быть 100 000 товаров.
У вас есть идеи, как сделать это быстрее?
class Product(...):
...
@property
def price(self):
for filter in self.user.filters():
if filter.get_queryset().filter(pk=self.pk).exists():
return filter.rule.apply_rule(self.price)
class ProductFilter(BaseTimeStampedModel):
project = models.ForeignKey('projects.UserEshop', related_name='product_filters', on_delete=models.CASCADE)
order = models.IntegerField(default=0)
name = models.CharField(max_length=64)
categories = models.ManyToManyField('FeedCategory', blank=True)
brands = models.ManyToManyField('Brand', blank=True)
manufacturers = models.ManyToManyField('Manufacturer', blank=True)
import_price_no_vat_max = models.DecimalField(decimal_places=2, max_digits=64, null=True, blank=True)
import_price_no_vat_min = models.DecimalField(decimal_places=2, max_digits=64, null=True, blank=True)
name_icontains = models.CharField(max_length=128, null=True, blank=True)
def get_queryset(self):
# products for this project
qs = Product.objects.filter(source__user_eshop=self.project)
if self.categories.exists():
qs = qs.filter(category__in=self.categories.all().get_descendants(include_self=True))
if self.brands.exists():
qs = qs.filter(brand__in=self.brands.all())
if self.manufacturers.exists():
qs = qs.filter(manufacturer__in=self.manufacturers.all())
if self.import_price_no_vat_max is not None:
qs = qs.filter(import_price_no_vat__lte=self.import_price_no_vat_max)
if self.import_price_no_vat_min is not None:
qs = qs.filter(import_price_no_vat__gte=self.import_price_no_vat_min)
if self.name_icontains:
qs = qs.filter(name__icontains=self.name_icontains)
return qs
РЕДАКТИРОВАТЬ
Моя лучшая идея заключается в том, чтобы создайте ManyToManyField
для ProductFilter
до Product
и каждый раз, когда что-то меняется, я назначаю продукты каждому фильтру. Я просто не уверен, что с ManyToManyField
можно хранить тысячи или сотни тысяч товаров.