0

For reducing the number of queries when people access frequently queried foreign key references, I've created a custom manager which includes select_related always for the foreign key relation. Now that there are places in code where people have used only on this same model when creating a query set. How can I override only query set method to include this foreign key relation always.

class CustomManager(models.Manager):                                        
    def get_queryset(self):                                                      
        return super(CustomManager, self).get_queryset().select_related('user')

When this model is used as below, I run into an error which says Field cannot be both deferred and traversed using select_related at the same time.

Model.objects.only('id','field_1').get(pk=1)

Anyway to mitigate this? I've to use select_related as above, since it will save lot of queries.

Santhosh
  • 130
  • 1
  • 2
  • 11
  • You might be able to use `prefetch_related()` instead. This will be one extra query, but it won't be n+1. Personally I wouldn't worry about using `only()`, though. The only time it is useful is when you have really large fields you don't want to load. For most use-cases it won't make any noticeable difference. You also might be able to use `values()` or `values_list()` instead of `only()`, but your code is not quite clear enough to see what you're doing, exactly. – Tom Carrick May 27 '20 at 11:23
  • @TomCarrick People have already used `only` in the repository at many places which I can't change one by one. Since I am selecting `user` always when someone queries this table, I am running into an issue as written above. I was looking for a way to include `user` as well in `only` for those instances. – Santhosh May 27 '20 at 11:34
  • Ok, have you tried with `prefetch_related()` instead of `select_related()`? They are very similar, except with `prefetch_related()` there is one extra query, but you have more control over it. – Tom Carrick May 27 '20 at 11:42
  • Actually I am trying to avoid that extra query here, which is very frequent in fact. – Santhosh May 27 '20 at 12:12
  • I think you misunderstand. If `select_related()` reduces from 100 queries to 1, `prefetch_related()` will reduce it from 100 to 2. This is still a useful saving. If this isn't good enough, the answer is "no, not without monkey patching django". The actual solution here is to tell people to stop using `only()`, and to remove the existing occurrences. It's a simple removal that won't cause any problems. – Tom Carrick May 27 '20 at 12:29

0 Answers0