Coder’s Eye

A site about one of the three passions in my life.

Coder’s Eye header image 2

Django Formatter Mixin Class

December 27th, 2006 · No Comments

GuitarI’ve always disliked having to write __repr__ methods for my classes. It isn’t hard, it is just tedious. In Django, it is especially important to make them, since the admin pages use that method when listing objects from the data model.

However, since Python allows classes to have multiple inheritance, I have long since made a helper “Mixin” class to remove most of the pain from writing my __repr__ methods. If you haven’t heard the term, a “Mixin” is a class which adds functionality to classes which inherit from it. The philosophy is that it shouldn’t change base functionality, thus avoiding many of the problems with multiple inheritance.

Philosophy aside, mixins can be extremely useful, and I love this one.I use it to provide a default __repr__ and to add a utility method which makes writing custom __repr__ methods extremely easy.

Example use

This is from the model for my Invisible Castle RPG site:


class Roll((models.Model, FormatterMixin):
    [… model code here …]>

    def __repr__(self):
        return self.make_repr(”Roll: “, ‘id’, ‘name’, ‘dice’, ‘rolls’, ‘results’)

Isn’t that nice? It makes the roll objects automatically have a repr which looks something like this: “Roll: id=1, name=example, dice=1d6, rolls=1, results=3″

If I had entirely omitted the __repr__ function above, it would still return: “Roll: id=1″

The mixin


"""
Utility functions for nicely formatting django models

:Author: Bruce Kroeze
:Contact: brucek@solidsitesolutions.com
:Copyright: Bruce Kroeze (c) 2006
:License: LGPL

Classes:

- `FormatterMixin`: A class which helps its implementers make nice looking __repr__ methods.

Functions:

- `get_field`: Get a field from an object, trying both the named property and its
"get_" version.

"""
__docformat__ = 'restructuredtext'

class FormatterMixin(object):
    """A class which helps its implementers make nice looking __repr__ methods.
    """

    def get_field(self, field, fallback=None):
        """Get a field from this object, trying both the named property and its
        "get_" version.

        Parameters:
        - `field`: to look up
        - `fallback`: default value

        Returns:
        - field value

        """
        return get_field(self, field, fallback)

    def make_repr(self, title, *args):
        """Create a string using the fields requested.

        Parameters:
        - `self`
        - `title`: to put at the beginning of the string
        - `args`: a list of fields to put in the string

        Returns:
        - string
        """
        rep = [title]
        rep.extend(["%s=%s, " % (field, self.get_field(field, "ATTRIBUTE MISSING"))
                    for field in args])

        ret = "".join(rep)
        if (ret.endswith(", ")):
            ret = ret[:-2]
        return ret

    def __repr__(self):
        return self.make_repr(self.__class__.__name__, 'id')

def get_field(obj, field, fallback=None):
    """Get a field from this object, trying both the named property and its
    "get_" version.

    Parameters:
    - `obj`
    - `field`: to look up
    - `fallback`: default value

    Returns:
    - field value
    """

    try:
        # simple object property
        return obj.__dict__[field]
    except KeyError:
        pass

    try:
        # class property
        return obj.__getattribute__(field)
    except AttributeError:
        pass

    # getter
    getter = 'get_%s' % field
    try:
        func = obj.__getattribute__(getter)
        return func()
    except AttributeError:
        pass

    return fallback

Technorati Tags: , ,

Tags: Tips · Django · Open Source · Python

Bookmark this article

del.icio.us:Django Formatter Mixin Class digg:Django Formatter Mixin Class spurl:Django Formatter Mixin Class wists:Django Formatter Mixin Class simpy:Django Formatter Mixin Class newsvine:Django Formatter Mixin Class blinklist:Django Formatter Mixin Class furl:Django Formatter Mixin Class reddit:Django Formatter Mixin Class fark:Django Formatter Mixin Class blogmarks:Django Formatter Mixin Class Y!:Django Formatter Mixin Class smarking:Django Formatter Mixin Class magnolia:Django Formatter Mixin Class segnalo:Django Formatter Mixin Class gifttagging:Django Formatter Mixin Class

0 responses so far ↓

  • There are no comments yet...Kick things off by filling out the form below.

Leave a Comment