Common querys as propertys

I have some question about what a good idea is to add common querysets as a model property, for example, in a social network the principle model is the user, the user is related with a set of chats, events, friendships, posts, etc. My first approach was to try to put all of this as method in a custom Queryset for each model, for example:

class PostQueryset(models.Queryset):
  def of_user(user):
     # return all the post with the user as owner

class ChatQueryset(models.Queryset):
  def of_user(user):
    # return all the chats where user1=user or user2=user


But what problems could I cause if I provide these querysets directly as properties in the model

class User(models.User):
  def posts(self):
    return Post.objects.of_user(self)

  def chats(self):
    return Chat.objects.of_user(self)

In this way, when i going to retry the data in the view, i only need to use something like request.user.posts. The only drawback I have seen is that it may seem strange to keep filtering with that queryset, like request.user.posts.filter(...some condition...), exists some others drawbacks?

The biggest potential drawbacks I see for doing it this way is that a view containing multiple users is going to generate 2n+1 queries for rendering the page. Even with a view only looking at one user, you’re generating three separate queries.

I’d probably more be looking at a custom manager (possibly with the aid of a custom queryset) that filters data appropriately along with using select_related or prefetch_related clauses to reduce the total number of queries. (This is less true if you’re just pulling one user - using prefetch_related to retrieve the reverse relationships is still going to create extra queries.)

Personally, my preference is to do all the work in the view to retrieve data to avoid having a template issuing queries.

Exists some severe problem with do heavy tasks like fetch a query in the template?. Your reasoning makes totally sense to me, but i found alternatives that extend my original idea, but including a cache with the cached_property decorator, this is some example.

I think on the surface it could be said that both are ways of optimizing, but in the major of the cases, your approach is the best. However when some form of cache is involved, the propertys cache fits better. My question is whether it is really bad to fetch querys on the template, because if the cached is implemented over redis, this is equal a one TCP requests to the redis server (more cheap that the request to the DB plus the extra processing) but at the end of the bill it can be considered a delayed process.

I have seen that they recommend not to do heavy tasks in the template, but what is heavy?, it is a CPU-time consume process or is a I/O request, this apply when you are using a django version without async (because in the async version totally makes sense not to block the event loop) or in the sync versions this don’t really matter, at the end of the bill is a one to one relation between one thread and one handler request.

There are two different issues that you want to avoid.

The first, and most serious one, is the “N+1 Query” problem. This occurs when you’re issuing a query to get a list of objects, and then executing a second query for each element of the list. This is bad, potentially extremely bad. The issue of having functions in your class that look like local variables but actually execute queries is that it’s very easy to accidentally create N+1 situations because it’s not obvious to the person building a template that the reference to that entity is actually generating a query.

The second issue, one that is more subjective and opinionated, is that this pattern leads to “confusion of concerns”. We use a design principle that all data access is done in the view. The data must be gathered in the view and passed to the template through the context. No data retrieval or business logic is allowed to exist in the templates. (This principle comes from a long unpleasant history of working with Java-based applications containing business logic and data retrievals in both servlets and JSPs. Understanding and debugging problems in such systems is much more difficult than it should be.)