def _get_value(self): primitive_models_dict = MetaModel.get_primitive_models_dict() mtype = primitive_models_dict.get(self.model_id, None) if mtype: mtype = mtype.name if mtype == 'BooleanField': return bool(self.decimal_value) if mtype == 'CharField': return self.unicode_value if mtype == 'DateField': return date.fromordinal(self.decimal_value) if mtype == 'DateTimeField': epoch = datetime.utcfromtimestamp(0) delta = timedelta(seconds=int(self.decimal_value)) return epoch + delta if mtype == 'DecimalField': return self.decimal_value if mtype == 'FileField': return FieldFile(default_storage.open(self.unicode_value), FileField(), self.unicode_value) if mtype == 'IntegerField': return int(self.decimal_value) return self.__getattr__('value')
def _set_value(self, new_value): mtype = MetaModel.get_primitive_models_dict()[self.model_id].name if mtype == 'BooleanField': if not isinstance(new_value, bool): raise ValueError self.decimal_value = int(new_value) self.unicode_value = None if mtype == 'CharField': if not isinstance(new_value, str): raise ValueError self.unicode_value = str(new_value) self.decimal_value = None if mtype == 'DateField': if not isinstance(new_value, date): raise ValueError self.decimal_value = new_value.toordinal() self.unicode_value = None if mtype == 'DateTimeField': if not isinstance(new_value, datetime): raise ValueError epoch = datetime.utcfromtimestamp(0) self.decimal_value = (new_value.replace(tzinfo=None) - epoch).total_seconds() self.unicode_value = None if mtype == 'DecimalField': self.decimal_value = Decimal(new_value) self.unicode_value = None if mtype == 'FileField': if isinstance(new_value, File): self.unicode_value = new_value.name self.decimal_value = None return if not isinstance(new_value, str): raise ValueError self.unicode_value = str(new_value) self.decimal_value = None if mtype == 'IntegerField': if not isinstance(new_value, int): raise ValueError self.decimal_value = new_value self.unicode_value = None
def get_or_create_with_value(cls, parent, field, value): from metamodel.models import MetaModel primitive_models_dict = MetaModel.get_primitive_models_dict() if field.multiple: raise Exception('This method is only consistent for ' 'non-multiple fields') try: instance_field = cls.objects.get(parent=parent, field=field) if value is None or value == '': instance_field.delete() return None if field.model_id in primitive_models_dict: instance_field.value.value = value instance_field.value.save() return instance_field except cls.DoesNotExist: if value is None or value == '': return instance_field = InstanceField(parent=parent, field=field) if field.model_id in primitive_models_dict: instance_value = InstanceModel(model=field.model) instance_value.value = value instance_value.save() value = instance_value instance_field.value = value instance_field.save() return instance_field
def __setattr__(self, name, value): if name in [ 'id', 'decimal_value', 'unicode_value', 'unicode_representation', 'model_id', 'model' ]: return super(InstanceModel, self).__setattr__(name, value) primitive_models_dict = MetaModel.get_primitive_models_dict() if name == 'value' and self.model_id in primitive_models_dict: self._set_value(value) return if name.startswith('_'): return super(InstanceModel, self).__setattr__(name, value) from metamodel.models import InstanceField try: mf = MetaField.objects.get(parent=self.model, name=name) is_primitive = mf.model_id in primitive_models_dict if not mf.nullable and not mf.multiple and not is_primitive: if value is None: raise IntegrityError('This field cannot be None') InstanceField.get_or_create_with_value(self, mf, value) if not mf.nullable and not mf.multiple and is_primitive: if value is None: raise IntegrityError('This field cannot be None') InstanceField.get_or_create_with_value(self, mf, value) if mf.multiple and not is_primitive: InstanceField.objects.filter(field=mf, parent=self).delete() for individual_value in value: new_field = InstanceField( parent=self, field=mf, ) new_field.value = individual_value new_field.save() if mf.multiple and is_primitive: existing_fields = InstanceField.objects.filter(field=mf, parent=self) for field in existing_fields: field.value.delete() for individual_value in value: im = InstanceModel(model=mf.model) im.value = individual_value im.save() new_field = InstanceField( parent=self, field=mf, ) new_field.value = im new_field.save() if mf.nullable and not mf.multiple and not is_primitive: InstanceField.get_or_create_with_value(self, mf, value) if mf.nullable and not mf.multiple and is_primitive: InstanceField.get_or_create_with_value(self, mf, value) except MetaField.DoesNotExist: return object.__setattr__(self, name, value)
def is_model_primitive(self): primitive_models_dict = MetaModel.get_primitive_models_dict() return self.model_id in primitive_models_dict