How to use select_related or prefetch_related with @property?

Viewed 75

I have a model with a custom property:

class Product(models.Model):
  name = models.CharField(_('Name'), max_length=255)
  [...]
  @property
    def price(self):
        return (self.price_line_product.filter(table__standard=True,
                                              table__client=self.client)
                .first().price)

class PriceLine(models.Model):

    price = models.FloatField(_('Price'))
    product = models.ForeignKey(
        "client.Product",
        verbose_name=_('product'),
        related_name="price_line_product",
        on_delete=models.CASCADE,
    )
    table = models.ForeignKey(
        "price.PriceTable",
        verbose_name=_('table price'),
        on_delete=models.CASCADE,
        related_name="table_priceline",
    )

class PriceTable(models.Model):

    name = models.CharField(_('Name'), max_length=255)
    client = models.ForeignKey(
        "client.Client",
        verbose_name=_('client'),
        related_name="price_table_client",
        on_delete=models.CASCADE
    )
    standard = models.BooleanField(_('Standard'), default=False)


The price property will look in another table for the right data. price_line_product is the related_name to access it.

It works fine but I have a lot of SQL queries that are executed. I tried in my view to add prefetch_related: Product.objects.filter(deleted=False).prefetch_related('price_line_product') Django doesn't return any error but it doesn't change the number of requests.

How to force the ORM not to make duplicate requests?

EDIT: I tried with the object Prefetch in my qs:

.prefetch_related(Prefetch('price_line_product',
                            queryset=PriceLine.objects.select_related("table").filter(table__standard=True).order_by('id'))) \

It seems to work, but the problem is that I don't know how to filter it by client. I had put table__client=self.client in @property at the base.

0 Answers
Related