Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does get_FIELD_display (in django) work?

Tags:

I'm a novice in Django and Python, and recently came across a number of methods in Django docs, such as Model.get_FOO_display(). Help page says that you can substitute FOO for a name of a field. I've been trying to figure out how that is possible in Python and looked into 'Model' class souce. There I came across this:

    def _get_FIELD_display(self, field):         value = getattr(self, field.attname)         return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True) 

I can't understand how it's possible in Python to: 1) to write this

class Person(models.Model):     gender = models.CharField(max_length=1, choices=GENDER_CHOICES) p = Person(name='John', gender='M')  p.get_gender_display() 

So, how does Python 'change' FIELD (or FOO) into gender? Is it some sort of Python 'wicked' notation? (Sorry, I can't ask more clearly) Coud you point to some Python man page?

2) why the source from Model class declares _get_FIELD_display() with the leading underscore, but the Python doc extract from above writes "p.get_gender_display()" without the underscore? Again, could you please give a Python man page for this?

like image 572
Nick Borodulin Avatar asked Apr 20 '11 12:04

Nick Borodulin


People also ask

How Django knows to update VS insert?

The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.

What is the purpose of __ Str__ method in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model. # Create your models here. This will display the objects as something always in the admin interface.

How does Django inheritance work?

Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not. When the parent model tables are not created as tables it just acts as a container for common fields and methods.

How do I override a save in Django?

save() method from its parent class is to be overridden so we use super keyword. slugify is a function that converts any string into a slug. so we are converting the title to form a slug basically.


1 Answers

This is all managed via the metaclass - you'll see in the source that the Model class defines a __metaclass__ attribute, which is set to ModelBase. The metaclass is to the class as a class is to an instance.

So the metaclass is called when a Django class is defined. The metaclass then executes various code which determines the properties of the model class. So, it iterates through the fields that are declared on the model class, and assigns each one as an instance attribute - this is how Django's declarative syntax works. It then calls each field's contribute_to_class method, which adds any field-specific methods to the class itself - and one of those methods is the _get_FOO_display method. You can see the source for this in django/db/models/fields/__init__.py.

In order to change _get_FIELD_display to get_myfieldname_display, it uses a technique called "currying", which means that it defines a new function that applies the original method with a defined parameter - in this case, the name of the field.

If you're interested in all this, Marty Alchin's book Pro Django has an excellent explanation.

like image 86
Daniel Roseman Avatar answered Sep 24 '22 22:09

Daniel Roseman