Login

Class ModelInfo for show object info

Author:
marinho
Posted:
July 1, 2008
Language:
Python
Version:
.96
Score:
1 (after 3 ratings)

This class works in compatibility with a ModelForm, but instead of show a form, it shows the field values.

The Meta class attributes can be used to customize fields to show, to be excluded, to divide by sections, to urlize text fields, etc.

Example 1:

class InfoSingleCertificate(ModelInfo):
    class Meta:
        model = SingleCertificate
        sections = (
            (None, ('vessel','description','document','comments','status',)),
            ('Issue', ('issue_date','issue_authority','issue_location',)),
        )

Example 2:

class InfoSingleCertificate(ModelInfo):
    class Meta:
        model = SingleCertificate
        fields = ('vessel','description','document','comments','status',
            'issue_date','issue_authority','issue_location',)

How to use:

Just save this snippet as a file in your project, import to your views.py module (or a new module named "info.py") and create classes following seemed sytax you use for ModelForms.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
from django.utils.safestring import mark_safe
from django.db import models
from django.template.defaultfilters import yesno, linebreaksbr, urlize
from django.utils.translation import get_date_formats
from django.utils.text import capfirst
from django.utils import dateformat

class ModelInfo(object):
    class _Meta:
        model = None
        fields = ()
        exclude = ()
        sections = None
        row_template = '<tr><th>%s</th><td>%s</td></tr>'
        show_if_none = False
        auto_urlize = True
        auto_linebreaks = True

    def __init__(self, instance, *args, **kwargs):
        self.instance = instance

        self._meta = self.Meta()
        _meta = self._Meta()

        for attr in ('model','fields','exclude','sections','row_template','show_if_none',
                'auto_urlize','auto_linebreaks',):
            if not hasattr(self._meta, attr):
                setattr(self._meta, attr, getattr(_meta, attr))

    def get_model_fields(self):
        return [f.name for f in self._meta.model._meta.fields \
                if f.name != 'id' and \
                (f.name in self._meta.fields or \
                not f.name in self._meta.exclude)\
                ]

    def get_field(self, f_name):
        return [f for f in self._meta.model._meta.fields if f.name == f_name][0]

    def get_field_display_text(self, f_name):
        return self.get_field(f_name).verbose_name

    def get_field_display_value(self, f_name):
        field = self.get_field(f_name)

        try:
            return getattr(self, 'get_%s_value'%f_name)
        except:
            pass

        f_value = getattr(self.instance, f_name)

        if f_value is None:
            return None

        if callable(f_value):
            return f_value()
        
        if isinstance(f_value, models.Model):
            if self._meta.auto_urlize and hasattr(f_value, 'get_absolute_url'):
                return '<a href="%s">%s</a>'%(f_value.get_absolute_url(), f_value)
            else:
                return unicode(f_value)

        if field.choices:
            return dict(field.choices).get(f_value, None)

        if isinstance(field, models.BooleanField):
            return yesno(f_value)

        date_format, datetime_format, time_format = get_date_formats()

        if isinstance(field, models.DateTimeField):
            return capfirst(dateformat.format(f_value, datetime_format))

        if isinstance(field, models.TimeField):
            return capfirst(dateformat.time_format(f_value, time_format))

        if isinstance(field, models.DateField):
            return capfirst(dateformat.format(f_value, date_format))

        if isinstance(field, models.TextField):
            if self._meta.auto_urlize: f_value = urlize(f_value)
            if self._meta.auto_linebreaks: f_value = linebreaksbr(f_value)

        return f_value

    def as_string(self):
        ret = []

        sections = self._meta.sections or ((None, self._meta.fields or self.get_model_fields()),)

        for s_name, s_fields in sections:
            if s_name:
                ret.append(self._meta.row_template%('&nbsp;', '<h3>%s</h3>'%s_name))
                
            for f_name in s_fields:
                f_display = self.get_field_display_text(f_name)
                f_display = f_display[0] == f_display[0].lower() and f_display.capitalize() or f_display

                f_value = self.get_field_display_value(f_name)

                if self._meta.show_if_none or f_value is not None:
                    ret.append(self._meta.row_template%(f_display, f_value))

        return mark_safe('\n'.join(ret))

    def __unicode__(self):
        return self.as_string()

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 3 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

marinho (on July 4, 2008):

Fixed methods get_model_fields and get_field

#

wandersean (on August 18, 2010):

I'm using this, thanks marinho.

One question: It's been a while since you posted this, are you still using it, or is there now a better way to get this info easily?

#

Please login first before commenting.