DEV Community

Cover image for How ORM(Object-Relational Mapping) uses the descriptor protocol?
Sumit Roy
Sumit Roy

Posted on

1 2

How ORM(Object-Relational Mapping) uses the descriptor protocol?

Recap

(Nostalgia)
From my previous post, we understood what is descriptor protocol and how to use it in many cases. How to modify the .(dot) operator and changing behaviour while setting the value.

Coming to the point

You might have heard about Django, and also about how cool is it's ORM. You can define classes and that's it. It will handle all the complexities of the backend database.

You can declare tables as class, columns as class attributes and rows as objects of that class

# of course you need to import models of Django.
class User(models.Model):
    email = models.CharField(max_length=50)
    mobile = models.IntegerField()
...
Enter fullscreen mode Exit fullscreen mode

So this class will be treated as user table and entries in this table are basically objects of this class. To handle fetch, update and filter out queries Django uses manager. There is a default manager provided by Django but you can modify it.

class UserManager(models.Manager):
    def get_queryset(self):
...
# this will modify _filter_ behaviour.
Enter fullscreen mode Exit fullscreen mode

So all these cool features Djnago gives in its ORM and many more.

Some familiar instances

If you have used Django ORM or any other similar, you might have come across something like this

...
class Order(models.Model):
    user = models.ForeignKey(User)
...

Enter fullscreen mode Exit fullscreen mode

Now suppose we want to change any attribute_(say first_name)_ of a user via order instance. So we will have to do something like this

...
o.user.first_name = "Sumit"
...
Enter fullscreen mode Exit fullscreen mode

Here Django uses their famous ForwardManyToOneDescriptor to handle the reference. If you want to check more on this you can go to their source code

Few lines are here

if value is not None and not isinstance(value, self.field.remote_field.model._meta.concrete_model):
            raise ValueError(
                'Cannot assign "%r": "%s.%s" must be a "%s" instance.' % (
                    value,
                    instance._meta.object_name,
                    self.field.name,
                    self.field.remote_field.model._meta.object_name,
                )
            )
Enter fullscreen mode Exit fullscreen mode

It checks the type of value, whether it matches the instance of the related class or not.

Conclusion

So basically even though we don't use descriptor protocol in our day to day coding but this is one secret that the guys building the framework knows and it's a nice tool to have.

Liked my post?

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay