Descriptor Protocol (2 Part Series)
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.
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() ...
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.
So all these cool features Djnago gives in its ORM and many more.
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) ...
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" ...
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, ) )
It checks the type of value, whether it matches the instance of the related class or not.
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.