PageRenderTime 27ms CodeModel.GetById 13ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/polymorphic/showfields.py

https://bitbucket.org/bconstantin/django_polymorphic/
Python | 150 lines | 116 code | 22 blank | 12 comment | 26 complexity | c2b34d6964245a09fd7566fe716d18db MD5 | raw file
  1# -*- coding: utf-8 -*-
  2
  3from django.db import models
  4from pprint import pformat
  5
  6class ShowFieldBase(object):
  7    """ base class for the ShowField... model mixins, does the work """
  8
  9    polymorphic_query_multiline_output = True # cause nicer multiline PolymorphicQuery output
 10
 11    polymorphic_showfield_type = False
 12    polymorphic_showfield_content = False
 13
 14    # these may be overridden by the user
 15    polymorphic_showfield_max_line_width = None
 16    polymorphic_showfield_max_field_width = 20
 17    polymorphic_showfield_old_format = False
 18
 19    def __repr__(self):
 20        return self.__unicode__()
 21
 22    def _showfields_get_content(self, field_name, field_type=type(None)):
 23        "helper for __unicode__"
 24        content = getattr(self, field_name)
 25        if self.polymorphic_showfield_old_format: out = ': '
 26        else: out = ' '
 27        if issubclass(field_type, models.ForeignKey):
 28            if content is None: out += 'None'
 29            else: out += content.__class__.__name__
 30        elif issubclass(field_type, models.ManyToManyField):
 31            out += '%d' % content.count()
 32        elif type(content) in (int,long):
 33            out += unicode(content)
 34        elif content is None:
 35            out += 'None'
 36        else:
 37            txt=unicode(content)
 38            if len(txt)>self.polymorphic_showfield_max_field_width:
 39                txt=txt[:self.polymorphic_showfield_max_field_width-2]+'..'
 40            out += '"' + txt + '"'
 41        return out
 42
 43    def _showfields_add_regular_fields(self, parts):
 44        "helper for __unicode__"
 45        done_fields = set()
 46        for field in self._meta.fields + self._meta.many_to_many:
 47            if field.name in self.polymorphic_internal_model_fields or '_ptr' in field.name: continue
 48            if field.name in done_fields: continue # work around django diamond inheritance problem
 49            done_fields.add(field.name)
 50            
 51            out = field.name
 52
 53            # if this is the standard primary key named "id", print it as we did with older versions of django_polymorphic
 54            if field.primary_key and field.name=='id' and type(field)==models.AutoField:
 55                out += ' '+ unicode(getattr(self, field.name))
 56
 57            # otherwise, display it just like all other fields (with correct type, shortened content etc.)
 58            else:
 59                if self.polymorphic_showfield_type:
 60                    out += ' (' + type(field).__name__
 61                    if field.primary_key: out += '/pk'
 62                    out += ')'
 63
 64                if self.polymorphic_showfield_content:
 65                    out += self._showfields_get_content(field.name,type(field))
 66
 67            parts.append((False, out,','))
 68
 69    def _showfields_add_dynamic_fields(self, field_list, title, parts):
 70        "helper for __unicode__"
 71        parts.append( ( True, '- '+title, ':' ) )
 72        for field_name in field_list:
 73            out = field_name
 74            content = getattr(self, field_name)
 75            if self.polymorphic_showfield_type:
 76                out += ' (' + type(content).__name__ + ')'
 77            if self.polymorphic_showfield_content:
 78                out += self._showfields_get_content(field_name)
 79
 80            parts.append( ( False, out, ',' ) )
 81
 82    def __unicode__(self):
 83        # create list ("parts") containing one tuple for each title/field:
 84        # ( bool: new section , item-text , separator to use after item )
 85
 86        # start with model name
 87        parts = [ (True, self.__class__.__name__, ':') ]
 88
 89        # add all regular fields
 90        self._showfields_add_regular_fields(parts)
 91
 92        # add annotate fields
 93        if hasattr(self,'polymorphic_annotate_names'):
 94            self._showfields_add_dynamic_fields(self.polymorphic_annotate_names, 'Ann', parts)
 95
 96        # add extra() select fields
 97        if hasattr(self,'polymorphic_extra_select_names'):
 98            self._showfields_add_dynamic_fields(self.polymorphic_extra_select_names, 'Extra', parts)
 99
100        # format result
101
102        indent = len(self.__class__.__name__)+5
103        indentstr = ''.rjust(indent)
104        out=u''; xpos=0; possible_line_break_pos = None
105
106        for i in xrange(len(parts)):
107            new_section, p, separator = parts[i]
108            final = (i==len(parts)-1)
109            if not final:
110                next_new_section, _, _ = parts[i+1]
111
112            if ( self.polymorphic_showfield_max_line_width
113                and xpos+len(p) > self.polymorphic_showfield_max_line_width
114                and possible_line_break_pos!=None ):
115                rest = out[possible_line_break_pos:]
116                out = out[:possible_line_break_pos]
117                out+= '\n'+indentstr+rest
118                xpos=indent+len(rest)
119
120            out += p; xpos += len(p)
121
122            if not final:
123                if not next_new_section:
124                    out += separator; xpos += len(separator)
125                out += ' '; xpos += 1
126
127            if not new_section:
128                possible_line_break_pos=len(out)
129
130        return u'<'+out+'>'
131
132
133class ShowFieldType(ShowFieldBase):
134    """ model mixin that shows the object's class and it's field types """
135    polymorphic_showfield_type = True
136
137class ShowFieldContent(ShowFieldBase):
138    """ model mixin that shows the object's class, it's fields and field contents """
139    polymorphic_showfield_content = True
140
141class ShowFieldTypeAndContent(ShowFieldBase):
142    """ model mixin, like ShowFieldContent, but also show field types """
143    polymorphic_showfield_type = True
144    polymorphic_showfield_content = True
145
146
147# compatibility with old class names
148ShowFieldTypes = ShowFieldType
149ShowFields = ShowFieldContent
150ShowFieldsAndTypes = ShowFieldTypeAndContent