0

How to Make Things Less Complicated With Django Model Managers

 1 year ago
source link: https://hackernoon.com/how-to-make-things-less-complicated-with-django-model-managers
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to Make Things Less Complicated With Django Model Managers

How to Make Things Less Complicated With Django Model Managers

February 23rd 2023 New Story
5 min
by @simplifiedweb

Dev Mehta

@simplifiedweb

Full Stack Web & Android Developer, Part-time Blogger. I love...

Read this story in a terminal
🖨️
Print this story

Too Long; Didn't Read

In this article, we will learn about django model managers. A manager manages a set of models and a model is just a row in that table. By default, Django adds a `Manager` with name `objects` to every Django model class. However, if you want to use ` objects` as a field name, or if you. want to define a name for the `Manager, you can rename it on. that class. For example, if I wanted all posts to start with how_to, I could use a manager that starts with how to.
featured image - How to Make Things Less Complicated With Django Model Managers
Your browser does not support theaudio element.
Read by Dr. One (en-US)
Audio Presented by

@simplifiedweb

Dev Mehta

Full Stack Web & Android Developer, Part-time Blogger. I ...

In this article, we will learn about Django model managers. Recently, when I was scrolling through the r/django Reddit community, I was excited to help other Django developers solve their errors.

I went through some posts and read the problems to get started, and I found the first problem I liked to solve.

The problem was “I would like to apply logic to my apps by having methods written in models.py. What is the best way to go about this? The documentation is great for the basics but I am getting frustrated when working to apply business logic outside of views.py. Any good resources on this type of flow? Business Logic in models.py?

You may have faced this frustration too sometimes because Django is a robust framework for perfectionists with deadlines; it expects us to figure this out ourselves (Or, so I thought because this question was very well covered in the documentation, which, if you’re like me, you might not have read it).

So, I gave them the solution that I generally use to write repetitive or common Django filter queries in the models.py file where you define your models, like this:

from  django.db import models

class Post(models.Model):
    title = models.CharField(max_length=70)
    # ...
    
    def get_howto_guides(self):
        return Post.objects.filter(title__istartswith="how to")

At first, I didn't see anything wrong with this. I was still learning and trying to make things work. But soon, people on Reddit pointed out that this approach was not optimal, and that the best place for this is the manager.

A manager manages a set of models (so basically, an SQL table), and a model is just a row in that table (it shouldn't know about other rows). And boy, I was embarrassed.

I soon realized that as our codebase will grow, our models will become bloated with business logic that was better suited to our model managers.

It wasn't until I stumbled across the concept of model managers that I realized there was a better way to organize my code(If you use Reddit, join r/django. You will learn so many new things daily).

Model managers, I learned, are a way to encapsulate model-level operations and queries in a clean and modular way.

How to Do It

By default, Django adds a Manager with the name objects to every Django model class. However, if you want to use objects as a field name, or if you want to use a name other than objects for the Manager, you can rename it on a per-model basis.

To rename the Manager for a given class, define a class attribute of type models.Manager() on that model. For example:

from django.db import models

class Post(models.Model):
    # ...
    how_to = models.Manager()

Here, Post.how_to will generate an AttributeError , while Post.how_to.all() returns all the objects from that manager.

Now, I can fit all my business logic about “How to Guide Posts” in my how_to model manager. For example, if I wanted all the posts that start with How to, or are basically how-to-do-x type of articles, I will write the following model manager separately for those kinds of posts.

from django.db import models

class HowtoPostsManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(title__istartswith="how to")
        # istartswith lookup field is used to
        # lookup case-insensitive titles.
        
class Post(models.Model):
    # ...
    objects = models.Manager() # Default Manager
    how_to = models.HowtoPostsManager() # our custom manager

Now, Post.objects.all() will return all the posts from the database, while Post.how_to.all(), will return only posts whose title starts with “How to”.

This example also pointed out another interesting technique: using multiple managers on the same model. You can attach as many Manager() instances to a model as you’d like. This is a non-repetitive way to define common “filters” for your models.

QuerySets as Model Managers

You can also define common filters as model managers in your Django models. For example:

from django.db import models

class HowtoQuery(models.QuerySet):
    def title_starts_with_howto(self):
        return self.filter(title__istartswith="how to")
        
class Post(models.Model):
    # ...
    objects = models.Manager() # Default Manager
    how_to = HowtoQuery.as_manager() # our custom manager

# This will be identicle to the previous code example,
# we looked at

Not every QuerySet method makes sense at the Manager level; for instance django prevents the QuerySet.delete() method from being copied onto the Manager class.

With model managers, I could write custom methods for my models that handled complex logic, filtering, and aggregation. I could also create new querysets that were specific to my application's needs which made it easier to reuse code across my views.

As I started to use model managers more in my applications, I found that my code was becoming cleaner and easier to read. I could also remove a lot of code from my models and keep my business logic closer to where it belonged.

In retrospect, it's hard to believe that I didn't know about model managers even after coding in Django for a considerable amount of time.

But I'm grateful that I came across this concept when I did, as it completely transformed the way I wrote code and helped me to become a better Django developer.

So, to anyone who is struggling with complex views and a messy codebase, I highly recommend exploring the power of model managers in Django. You might be surprised by how much they can simplify your code and improve your overall development experience.


Also published here


The Web Development and eCommerce Writing Contest is brought to you by Elastic Path in partnership with HackerNoon. Publish your thoughts and experiences on #eCommerce or #web-development to win a cash prize!

Elastic Path is the only commerce company making Composable Commerce accessible for tech teams with unique product merchandising requirements and complex go-to-market strategies. Explore our product today!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK