# some helpers for the proxy layer bridging the gap between the legacy # and the redesigned schema, eventually this should all go from django.db.models.manager import Manager from django.db.models.query import QuerySet def proxy_personify_role(role): """Turn role into person with email() method using email from role.""" p = role.person p.email = lambda: (p.plain_name(), role.email.address) return p def proxy_role_email(e): """Add email() method to person on email.""" e.person.email = lambda: (e.person.plain_name(), e.address) return e def chunks(l, n): """Split list l up in chunks of max size n.""" return (l[i:i+n] for i in xrange(0, len(l), n)) class TranslatingQuerySet(QuerySet): """Query set that can do some simple mappings of the filter args.""" def translated_args(self, args): trans = self.translated_attrs res = [] for a in args: if a.startswith("-"): prefix = "-" a = a[1:] else: prefix = "" if a in trans: t = trans[a] if callable(t): t, _ = t(None) if t: res.append(prefix + t) else: res.append(prefix + a) return res def translated_kwargs(self, kwargs): trans = self.translated_attrs res = dict() for k, v in kwargs.iteritems(): if k in trans: t = trans[k] if callable(t): ts = t(v) else: ts = (t, v) for t, v in chunks(ts, 2): if t: res[t] = v else: res[k] = v return res # overridden methods def _clone(self, *args, **kwargs): c = super(TranslatingQuerySet, self)._clone(*args, **kwargs) c.translated_attrs = self.translated_attrs return c def dates(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).dates(*args, **kwargs) def distinct(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).distinct(*args, **kwargs) def extra(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).extra(*args, **kwargs) def get(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).get(*args, **kwargs) def get_or_create(self, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).get_or_create(**kwargs) def create(self, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).create(**kwargs) def filter(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).filter(*args, **kwargs) def aggregate(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).aggregate(*args, **kwargs) def annotate(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).annotate(*args, **kwargs) def complex_filter(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).complex_filter(*args, **kwargs) def exclude(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).exclude(*args, **kwargs) def in_bulk(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).in_bulk(*args, **kwargs) def iterator(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).iterator(*args, **kwargs) def latest(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).latest(*args, **kwargs) def order_by(self, *args, **kwargs): args = self.translated_args(args) kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).order_by(*args, **kwargs) def select_related(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).select_related(*args, **kwargs) def values(self, *args, **kwargs): args = self.translated_args(args) kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).values(*args, **kwargs) def values_list(self, *args, **kwargs): args = self.translated_args(args) kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).values_list(*args, **kwargs) def update(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).update(*args, **kwargs) def reverse(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).reverse(*args, **kwargs) def defer(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).defer(*args, **kwargs) def only(self, *args, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self).only(*args, **kwargs) def _insert(self, values, **kwargs): kwargs = self.translated_kwargs(kwargs) return insert_query(self.model, values, **kwargs) def _update(self, values, **kwargs): kwargs = self.translated_kwargs(kwargs) return super(TranslatingQuerySet, self)._update(values, **kwargs) class TranslatingManager(Manager): """Translates keyword arguments for the ORM, for use in proxy wrapping, e.g. given trans={'foo': 'bar'} it will transform a lookup of the field foo to a lookup on the field bar. The right hand side can either be a string or a function which is called with the right-hand side to transform it.""" def __init__(self, trans, always_filter=None): super(TranslatingManager, self).__init__() self.translated_attrs = trans self.always_filter = always_filter def get_query_set(self): qs = TranslatingQuerySet(self.model) qs.translated_attrs = self.translated_attrs if self.always_filter: qs = qs.filter(**self.always_filter) return qs # def dates(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().dates(*args, **kwargs) # def distinct(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().distinct(*args, **kwargs) # def extra(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().extra(*args, **kwargs) # def get(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().get(*args, **kwargs) # def get_or_create(self, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().get_or_create(**kwargs) # def create(self, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().create(**kwargs) # def filter(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().filter(*args, **kwargs) # def aggregate(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().aggregate(*args, **kwargs) # def annotate(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().annotate(*args, **kwargs) # def complex_filter(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().complex_filter(*args, **kwargs) # def exclude(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().exclude(*args, **kwargs) # def in_bulk(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().in_bulk(*args, **kwargs) # def iterator(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().iterator(*args, **kwargs) # def latest(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().latest(*args, **kwargs) # def order_by(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().order_by(*args, **kwargs) # def select_related(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().select_related(*args, **kwargs) # def values(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().values(*args, **kwargs) # def values_list(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().values_list(*args, **kwargs) # def update(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().update(*args, **kwargs) # def reverse(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().reverse(*args, **kwargs) # def defer(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().defer(*args, **kwargs) # def only(self, *args, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set().only(*args, **kwargs) # def _insert(self, values, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return insert_query(self.model, values, **kwargs) # def _update(self, values, **kwargs): # kwargs = self.translated_kwargs(kwargs) # return self.get_query_set()._update(values, **kwargs)