Coverage for lino/utils/instantiator.py : 35%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# Copyright 2009-2014 Luc Saffre # License: BSD (see file COPYING for details)
used for generating database objects in :ref:`python fixtures <dpy>`.
Example values:
>>> s = '<a href="javascript:Lino.pcsw.Clients.detail.run(\ null,{ "record_id": 116 })">BASTIAENSEN Laurent (116)</a>' >>> GFK_HACK.match(s).groups() (u'pcsw.Clients', u'116')
>>> s = '<a href="javascript:Lino.cal.Guests.detail.run(\ null,{ "record_id": 6 })">Gast #6 ("Termin #51")</a>' >>> GFK_HACK.match(s).groups() (u'cal.Guests', u'6')
"""
return kw
""" A Converter for ForeignKey and ManyToManyField. If the lookup_field is a BabelField, then it tries all available languages. """
else: self.lookup_field = model._meta.get_field(lookup_field) #~ self.lookup_field = lookup_field
model = self.field.rel.model if isinstance(value, model): return value return model.lookup_or_create(self.lookup_field, value, **kw)
#~ if isinstance(self.lookup_field,babel.BabelCharField): #~ flt = babel.lookup_filter(self.lookup_field.name,value,**kw) #~ else: #~ kw[self.lookup_field.name] = value #~ flt = models.Q(**kw) #~ try: #~ return model.objects.get(flt) #~ except MultipleObjectsReturned,e: #~ raise model.MultipleObjectsReturned("%s.objects lookup(%r) : %s" % (model.__name__,value,e)) #~ except model.DoesNotExist,e: #~ raise model.DoesNotExist("%s.objects lookup(%r) : %s" % (model.__name__,value,e))
value = kw.get(self.field.name) if value is not None: if not isinstance(value, datetime.date): if type(value) == int: value = str(value) d = dateparser.parse(value) d = datetime.date(d.year, d.month, d.day) kw[self.field.name] = d return kw
"""Converter for :class:`ChoiceListField <lino.core.choicelists.ChoiceListField>`. """
value = kw.get(self.field.name)
if value is not None: if not isinstance(value, self.field.choicelist.item_class): kw[self.field.name] = self.field.choicelist.get_by_value(value) return kw
value = kw.get(self.field.name) if value is not None: if not isinstance(value, decimal.Decimal): kw[self.field.name] = decimal.Decimal(value) return kw
"""Converter for ForeignKey fields."""
value = kw.get(self.field.name) if value is not None: if value == '': value = None else: value = self.lookup(value) kw[self.field.name] = value #~ logger.info("20111213 %s %s -> %r", self.field.name,self.__class__,value) return kw
"""Converter for GenericForeignKey fields."""
value = kw.get(self.field.name) if value is not None: if value == '': value = None else: mo = GFK_HACK.match(value) if mo is not None: actor = settings.SITE.modules.resolve(mo.group(1)) pk = mo.group(2) value = actor.get_row_by_pk(None, pk) # ct = ContentType.objects.get_for_model(actor.model) # value = self.lookup(value) else: raise Exception("Could not parse %r" % value) kw[self.field.name] = value return kw
"""Converter for ManyToMany fields."""
#~ def lookup(self,value): #~ model = self.field.rel.model #~ try: #~ return model.objects.get( #~ **{self.lookup_field: value}) #~ except model.DoesNotExist,e: #~ raise DataError("%s.objects.get(%r) : %s" % ( #~ model.__name__,value,e))
values = kw.get(self.field.name) if values is not None: del kw[self.field.name] l = [self.lookup(value) for value in values.split(self.splitsep)] kw['_m2m'][self.field.name] = l return kw
return GenericForeignKeyConverter(f) #~ if isinstance(f,fields.LinkedForeignKey): #~ return LinkedForeignKeyConverter(f,lookup_fields.get(f.name,"pk")) return ManyToManyConverter(f, lookup_fields.get(f.name, "pk")) return DateConverter(f) return DecimalConverter(f) #~ if f.name == 'p_book': #~ print "20131012 b", f
"""A utility class to make python fixtures more compact. See :ref:`tutorial.instantiator`.
An instantiator is a
"""
#~ self.model = resolve_model(model,strict=True) self.model = resolve_model(model) if isinstance(self.model, UnresolvedModel): raise Exception("Instantiator on unresolved model %s", model) if not self.is_active(): def noop(*values, **kw): pass self.build = noop return #~ if self.model._meta.pk is None: #~ raise Exception("Model %r is not installed (_meta.pk is None)." % self.model) #~ if type(fieldnames) == str: if isinstance(fieldnames, basestring): fieldnames = fieldnames.split() self.default_values = kw #self.fieldnames = fieldnames lookup_fields = {} self.converters = [] if fieldnames is None: self.fields = self.model._meta.fields else: self.fields = [] for name in fieldnames: a = name.split(":") if len(a) == 2: name = a[0] lookup_fields[name] = a[1] field = self.model._meta.get_field(name) self.fields.append(field) # print " ".join(dir(model_class)) # print " ".join(model_class._meta.fields) # for f in model_class._meta.fields: # for f in self.fields: for f in self.model._meta.fields + self.model._meta.many_to_many: cv = None cvc = converter_classes.get(f.name, None) if cvc is not None: cv = cvc(f) else: cv = make_converter(f, lookup_fields) if cv is not None: self.converters.append(cv) #~ for f in model_class._meta.many_to_many: #~ print "foo", f.name
if isinstance(self.model, UnresolvedModel): return False if self.model._meta.pk is None: return False return True
"""Calling an instantiator is the same as callig its :meth:`build` method.
""" return self.build(*values, **kw)
"""Instantiate an object using the default values of this instantiator, overridden by the given specified values. The number of positional arguments may not exceed the number of fieldnames specified when creating this :class:`Instantiator`.
""" # logger.debug("Instantiator.build(%s,%r,%r)",self.model_class._meta.db_table,values,kw) #~ i = 0 kw['_m2m'] = {} for i, v in enumerate(values): if isinstance(v, basestring): v = v.strip() if len(v) > 0: kw[self.fields[i].name] = v else: kw[self.fields[i].name] = v #~ i += 1 #~ kw.update(self.default_values) for k, v in list(self.default_values.items()): kw.setdefault(k, v) for c in self.converters: kw = c.convert(**kw) #~ if self.model.__name__ == 'Company': #~ print 20130212, __file__, kw #~ logger.info("20130212 field_cache for %s (%s)",self.model, #~ ' '.join([f.name for f in self.model._meta._field_name_cache]))
m2m = kw.pop("_m2m") instance = self.model(**kw) instance.full_clean() if m2m: instance.save() for k, v in list(m2m.items()): queryset = getattr(instance, k) queryset.add(*v) return instance
""" Usage example see :mod:`lino_xl.lib.humanlinks.fixtures`. """ self._objects = [] self._instantiators = dict()
i = Instantiator(*args, **kw) # self._instantiators[i.model] = i
def f(*args, **kw): o = i.build(*args, **kw) return self.on_new(o) setattr(self, name, f)
self._objects.append(o) return o
rv = self._objects self._objects = [] return rv
""" Instantiate, full_clean, save and read back from database (the latter to avoid certain Django side effects) """ model = resolve_model(model) o = model(**kw) o.full_clean() o.save() return model.objects.get(pk=o.pk)
import doctest doctest.testmod()
_test() |