Getting data from other table in model property

Hi!

I have a model that has a dynamic property like:

class UserFund(models.Model):
    # field definitions here

    @property
    def user_currency_value(self):
        user_currency = self.user.currency
        fund_currency = self.fund.currency
        return self.fund.position * self.fund.price * <currency conversion here>

The information about conversion rates is stored in another table Currency.

How to do this calculation without making a lot of extra queries?

Is it OK to query the whole Currency table once and use that as a lookup table inside this user_currency_value function? Will this be cached somehow? Is there a better way to do this?

Thanks!

This (old) SO question is about the same problem I have: https://stackoverflow.com/questions/28598178/django-queryset-with-model-method-containing-another-queryset

The main control technique here is with prefetch_related or select_related on Currency, wherever you query UserFund: https://docs.djangoproject.com/en/3.0/topics/db/optimization/#retrieve-everything-at-once-if-you-know-you-will-need-it

You detect when you need such a call with this library: https://github.com/jmcarp/nplusone

If you’re feeling adventurous you can try this library, which I’m developing with my ex-boss: https://github.com/tolomea/django-auto-prefetch . It changes the N+1 behaviour down to 2 queries instead, by automatically using prefetch_related on access. We hope to get it into Django core.

Awesome!

For my understanding (I’m new to Django), in the answer here: https://stackoverflow.com/a/28598539/562267, would you apply prefetch_related in the MyModelManager?

Adding a prefetch_related() there would work. It could end up with overfetching though, as it will always prefetch, even on code paths that don’t touch your property.

1 Like