django hacks: accesing a model.field verbose_name...
My first django hack, imagine you have a model like:
class Project(models.Model):
""" A sample django model """
name = models.CharField('Project name', max_length=250)
start_date = models.DateField('Project started on')
employee = models.CharField('Project associated to', max_length=250)
def __unicode__(self):
return self.name
class Admin:
list_display = ('name', 'start_date', 'employee')
list_filter = ['employee']
search_fields = ['name']
class Meta:
ordering = ['-start_date']
verbose_name_plural = 'Projects';
Once we have our model, we can play with it through a python shell. In order to do that, we have to use the shell command of manage.py:
snowball:SomeProject wu$ python manage.py shell
This way, all the neccesary deps from django will be pre-loaded and we will end in a python console running inside our project environment. Then, we can do something like:
Python 2.5.2 (r252:60911, Apr 29 2008, 23:50:14)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from SomeProject.iapm.models import Project
>>> p = Project.objects.all()[0]
>>> p
<Project: francisco_2008_03>
>>>
Here, I've imported the Project model, which is a class, then I created an instance of that class getting some data from the database (the first entry in the projects list) and using such data to populate the attributes of the model's class (name, start_date and employee).
Next, I called the instance itself, which will call the __unicode__ method, which will return a unicode object contaning the project name.
Of course, I could check the different attributes of the instance, like the name:
>>> p.name
u'francisco_2008_03'
or the employee:
>>> p.employee
u'Wu'
With that, I got the value for each attribute but, what if I would like to show something like:
Atribute: value
Each field object have two attributes, name and verbose_name, that will show the name of the field when called. The problem appeared when I tried to access those attributes directly:
>>> p.employee.name
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'unicode' object has no attribute 'name'
>>> p.employee.verbose_name
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'unicode' object has no attribute 'verbose_name'
>>>
What happened here? Well, it is pretty easy to understand. When I called p.responsable what I got in return is an unicode object, which doesn't have nor a name attribute, neither a verbose_name attribute.
Well, thnx to theju in the #django irc channel (irc.freenode.net) I found a workaround:
>>> p._meta.get_field('responsable').verbose_name
'Responsable de proyecto'
Here, I called the get_field method to get a field object, which does have a verbose_name attribute. Easy, isn't it?
So I finally got something like:
>>> print p._meta.get_field('employee').verbose_name + ': ' + p.employee
Project associated to: Wu
Of course that could be used inside a view to, for example, create a list of empty attributes from a given model.