Package django :: Package contrib :: Package databrowse :: Module datastructures
[hide private]
[frames] | no frames]

Source Code for Module django.contrib.databrowse.datastructures

  1  """ 
  2  These classes are light wrappers around Django's database API that provide 
  3  convenience functionality and permalink functions for the databrowse app. 
  4  """ 
  5   
  6  from django.db import models 
  7  from django.utils import dateformat 
  8  from django.utils.text import capfirst 
  9  from django.utils.translation import get_date_formats 
 10  from django.utils.encoding import smart_unicode, smart_str, iri_to_uri 
 11  from django.utils.safestring import mark_safe 
 12  from django.db.models.query import QuerySet 
 13   
 14  EMPTY_VALUE = '(None)' 
 15   
16 -class EasyModel(object):
17 - def __init__(self, site, model):
18 self.site = site 19 self.model = model 20 self.model_list = site.registry.keys() 21 self.verbose_name = model._meta.verbose_name 22 self.verbose_name_plural = model._meta.verbose_name_plural
23
24 - def __repr__(self):
25 return '<EasyModel for %s>' % smart_str(self.model._meta.object_name)
26
27 - def model_databrowse(self):
28 "Returns the ModelDatabrowse class for this model." 29 return self.site.registry[self.model]
30
31 - def url(self):
32 return mark_safe('%s%s/%s/' % (self.site.root_url, self.model._meta.app_label, self.model._meta.module_name))
33
34 - def objects(self, **kwargs):
35 return self.get_query_set().filter(**kwargs)
36
37 - def get_query_set(self):
38 easy_qs = self.model._default_manager.get_query_set()._clone(klass=EasyQuerySet) 39 easy_qs._easymodel = self 40 return easy_qs
41
42 - def object_by_pk(self, pk):
43 return EasyInstance(self, self.model._default_manager.get(pk=pk))
44
45 - def sample_objects(self):
46 for obj in self.model._default_manager.all()[:3]: 47 yield EasyInstance(self, obj)
48
49 - def field(self, name):
50 try: 51 f = self.model._meta.get_field(name) 52 except models.FieldDoesNotExist: 53 return None 54 return EasyField(self, f)
55
56 - def fields(self):
57 return [EasyField(self, f) for f in (self.model._meta.fields + self.model._meta.many_to_many)]
58
59 -class EasyField(object):
60 - def __init__(self, easy_model, field):
61 self.model, self.field = easy_model, field
62
63 - def __repr__(self):
64 return smart_str(u'<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
65
66 - def choices(self):
67 for value, label in self.field.choices: 68 yield EasyChoice(self.model, self, value, label)
69
70 - def url(self):
71 if self.field.choices: 72 return mark_safe('%s%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name)) 73 elif self.field.rel: 74 return mark_safe('%s%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name))
75
76 -class EasyChoice(object):
77 - def __init__(self, easy_model, field, value, label):
78 self.model, self.field = easy_model, field 79 self.value, self.label = value, label
80
81 - def __repr__(self):
82 return smart_str(u'<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
83
84 - def url(self):
85 return mark_safe('%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value)))
86
87 -class EasyInstance(object):
88 - def __init__(self, easy_model, instance):
89 self.model, self.instance = easy_model, instance
90
91 - def __repr__(self):
92 return smart_str(u'<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
93
94 - def __unicode__(self):
95 val = smart_unicode(self.instance) 96 if len(val) > 30: 97 return val[:30] + u'...' 98 return val
99
100 - def __str__(self):
101 return self.__unicode__().encode('utf-8')
102
103 - def pk(self):
104 return self.instance._get_pk_val()
105
106 - def url(self):
107 return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, iri_to_uri(self.pk()))
108
109 - def fields(self):
110 """ 111 Generator that yields EasyInstanceFields for each field in this 112 EasyInstance's model. 113 """ 114 for f in self.model.model._meta.fields + self.model.model._meta.many_to_many: 115 yield EasyInstanceField(self.model, self, f)
116
117 - def related_objects(self):
118 """ 119 Generator that yields dictionaries of all models that have this 120 EasyInstance's model as a ForeignKey or ManyToManyField, along with 121 lists of related objects. 122 """ 123 for rel_object in self.model.model._meta.get_all_related_objects() + self.model.model._meta.get_all_related_many_to_many_objects(): 124 if rel_object.model not in self.model.model_list: 125 continue # Skip models that aren't in the model_list 126 em = EasyModel(self.model.site, rel_object.model) 127 yield { 128 'model': em, 129 'related_field': rel_object.field.verbose_name, 130 'object_list': [EasyInstance(em, i) for i in getattr(self.instance, rel_object.get_accessor_name()).all()], 131 }
132
133 -class EasyInstanceField(object):
134 - def __init__(self, easy_model, instance, field):
135 self.model, self.field, self.instance = easy_model, field, instance 136 self.raw_value = getattr(instance.instance, field.name)
137
138 - def __repr__(self):
139 return smart_str(u'<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
140
141 - def values(self):
142 """ 143 Returns a list of values for this field for this instance. It's a list 144 so we can accomodate many-to-many fields. 145 """ 146 # This import is deliberately inside the function because it causes 147 # some settings to be imported, and we don't want to do that at the 148 # module level. 149 if self.field.rel: 150 if isinstance(self.field.rel, models.ManyToOneRel): 151 objs = getattr(self.instance.instance, self.field.name) 152 elif isinstance(self.field.rel, models.ManyToManyRel): # ManyToManyRel 153 return list(getattr(self.instance.instance, self.field.name).all()) 154 elif self.field.choices: 155 objs = dict(self.field.choices).get(self.raw_value, EMPTY_VALUE) 156 elif isinstance(self.field, models.DateField) or isinstance(self.field, models.TimeField): 157 if self.raw_value: 158 date_format, datetime_format, time_format = get_date_formats() 159 if isinstance(self.field, models.DateTimeField): 160 objs = capfirst(dateformat.format(self.raw_value, datetime_format)) 161 elif isinstance(self.field, models.TimeField): 162 objs = capfirst(dateformat.time_format(self.raw_value, time_format)) 163 else: 164 objs = capfirst(dateformat.format(self.raw_value, date_format)) 165 else: 166 objs = EMPTY_VALUE 167 elif isinstance(self.field, models.BooleanField) or isinstance(self.field, models.NullBooleanField): 168 objs = {True: 'Yes', False: 'No', None: 'Unknown'}[self.raw_value] 169 else: 170 objs = self.raw_value 171 return [objs]
172
173 - def urls(self):
174 "Returns a list of (value, URL) tuples." 175 # First, check the urls() method for each plugin. 176 plugin_urls = [] 177 for plugin_name, plugin in self.model.model_databrowse().plugins.items(): 178 urls = plugin.urls(plugin_name, self) 179 if urls is not None: 180 #plugin_urls.append(urls) 181 values = self.values() 182 return zip(self.values(), urls) 183 if self.field.rel: 184 m = EasyModel(self.model.site, self.field.rel.to) 185 if self.field.rel.to in self.model.model_list: 186 lst = [] 187 for value in self.values(): 188 url = mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val()))) 189 lst.append((smart_unicode(value), url)) 190 else: 191 lst = [(value, None) for value in self.values()] 192 elif self.field.choices: 193 lst = [] 194 for value in self.values(): 195 url = mark_safe('%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value))) 196 lst.append((value, url)) 197 elif isinstance(self.field, models.URLField): 198 val = self.values()[0] 199 lst = [(val, iri_to_uri(val))] 200 else: 201 lst = [(self.values()[0], None)] 202 return lst
203
204 -class EasyQuerySet(QuerySet):
205 """ 206 When creating (or cloning to) an `EasyQuerySet`, make sure to set the 207 `_easymodel` variable to the related `EasyModel`. 208 """
209 - def iterator(self, *args, **kwargs):
210 for obj in super(EasyQuerySet, self).iterator(*args, **kwargs): 211 yield EasyInstance(self._easymodel, obj)
212
213 - def _clone(self, *args, **kwargs):
214 c = super(EasyQuerySet, self)._clone(*args, **kwargs) 215 c._easymodel = self._easymodel 216 return c
217