[Tutor] model methods in Django

eryksun eryksun at gmail.com
Sun May 19 08:03:22 CEST 2013


On Sat, May 18, 2013 at 10:22 PM, Dave Angel <davea at davea.name> wrote:
> The pub_date is probably an instance attribute of either the Poll class or
> the models.Model class.  It should probably be defined in the appropriate
> __init__ method.  In any case it's not a method attribute.

Django uses function attributes as metadata. The names "boolean" and
"short_description" are self-documenting. "admin_order_field" is
explained here:

https://docs.djangoproject.com/en/dev/ref/contrib/admin/
#django.contrib.admin.ModelAdmin.list_display

    Usually, elements of list_display that aren’t actual database
    fields can’t be used in sorting (because Django does all the
    sorting at the database level). However, if an element of
    list_display represents a certain database field, you can
    indicate this fact by setting the admin_order_field attribute
    of the item.

The Poll model is part of the tutorial, "Writing your first Django app":

https://docs.djangoproject.com/en/1.5/intro

The function attributes are added in "Customize the admin change
list", in part 2.

> Perhaps you didn't realize that a function can have attributes, and that
> they can be added to the function at any time after the function is created.
> Being a method doesn't change that.

In a class definition, from a conceptual point of view, you're adding
a 'method'. But technically it's a function object. When accessed as
an attribute, the function's __get__ descriptor is used to create a
method on the fly.

The instancemethod type has a custom __getattribute__ that first
checks the method object's attributes such as __self__. If the lookup
on the method object fails, it proxies the __getattribute__ of the
wrapped __func__. For example:

    class Spam(object):
        def __repr__(self):
            return 'eggs'

    >>> meth = Spam().__repr__
    >>> type(meth)
    <type 'instancemethod'>
    >>> meth.__self__
    eggs

A method doesn't have a __dict__ for setting dynamic attributes:

    >>> meth.boolean = False
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'instancemethod' object has no attribute 'boolean'

But you can set attributes on the underlying function object:

    >>> type(meth.__func__)
    <type 'function'>
    >>> meth.__func__.boolean = False

The method will proxy them:

    >>> meth.boolean
    False

But not for assignment:

    >>> meth.boolean  = True
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'instancemethod' object has no attribute 'boolean'


More information about the Tutor mailing list