def load_block(self, m_name, pk, data): """ Import a single block of fields into the given model. """ if self.deferred_models[m_name] > 3: # Model is deferred! return None try: model, fields = self.get_model(m_name) except base.DeserializationError: sys.stderr.write("\nSkipping all items from model {m_name}!\n") self.deferred_models[m_name] = 10 return None try: data = self.build_data(model, fields, pk, data) m2m_fields = data.pop('m2m', {}) except (base.M2MDeserializationError, base.DeserializationError, ObjectDoesNotExist): return None try: obj = base.build_instance(model, data, None) return base.DeserializedObject(obj, m2m_fields, {}) except Exception: return None # Any error, defer the object.
def __next__(self): if not self._current_row_is_valid(): """ If the current row is not valid, next will try to go to the next sheet and deserialize the first object. """ try: self._select_next_sheet() except: raise StopIteration # Build object: if self._current_row_is_valid(): values = self._row_to_dict(self.workbook.active[self.current_row], self.fields) obj = base.build_instance(self.model_class, values, False) obj.save() else: # Sheets without data (only with header): raise StopIteration # Updata row position: self.current_row += 1 return base.DeserializedObject(obj, {})
def _handle_object(self, node): """ Convert an <object> node to a DeserializedObject. """ # Look up the model using the model loading mechanism. If this fails, # bail. Model = self._get_model_from_node(node, "model") # Start building a data dictionary from the object. data = {} if node.hasAttribute('pk'): data[Model._meta.pk.attname] = Model._meta.pk.to_python( node.getAttribute('pk')) # Also start building a dict of m2m data (this is saved as # {m2m_accessor_attribute : [list_of_related_objects]}) m2m_data = {} field_names = {f.name for f in Model._meta.get_fields()} # Deserialize each field. for field_node in node.getElementsByTagName("field"): # If the field is missing the name attribute, bail (are you # sensing a pattern here?) field_name = field_node.getAttribute("name") if not field_name: raise base.DeserializationError( "<field> node is missing the 'name' attribute") # Get the field from the Model. This will raise a # FieldDoesNotExist if, well, the field doesn't exist, which will # be propagated correctly unless ignorenonexistent=True is used. if self.ignore and field_name not in field_names: continue field = Model._meta.get_field(field_name) # As is usually the case, relation fields get the special treatment. if field.remote_field and isinstance(field.remote_field, models.ManyToManyRel): m2m_data[field.name] = self._handle_m2m_field_node( field_node, field) elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel): data[field.attname] = self._handle_fk_field_node( field_node, field) else: if field_node.getElementsByTagName('None'): value = None else: value = field.to_python(getInnerText(field_node).strip()) data[field.name] = value obj = base.build_instance(Model, data, self.db) # Return a DeserializedObject so that the m2m data has a place to live. return base.DeserializedObject(obj, m2m_data)
def _handle_object(self, node): """ Convert an <object> node to a DeserializedObject. """ from django.core.serializers import xml_serializer getInnerText = xml_serializer.getInnerText # Look up the model using the model loading mechanism. If this fails, # bail. Model = self._get_model_from_node(node, "model") # Start building a data dictionary from the object. data = {} if node.hasAttribute('pk'): data[Model._meta.pk.attname] = Model._meta.pk.to_python( node.getAttribute('pk')) # Also start building a dict of m2m data (this is saved as # {m2m_accessor_attribute : [list_of_related_objects]}) m2m_data = {} # Deseralize each field. for field_node in node.getElementsByTagName("field"): # If the field is missing the name attribute, bail (are you # sensing a pattern here?) field_name = field_node.getAttribute("name") if not field_name: raise base.DeserializationError("<field> node is missing the 'name' attribute") # Get the field from the Model. This will raise a # FieldDoesNotExist if, well, the field doesn't exist, which will # be propagated correctly. field = Model._meta.get_field(field_name) # As is usually the case, relation fields get the special treatment. if field.rel and isinstance(field.rel, models.ManyToManyRel): m2m_data[field.name] = self._handle_m2m_field_node(field_node, field) elif field.rel and isinstance(field.rel, models.ManyToOneRel): data[field.attname] = self._handle_fk_field_node(field_node, field) else: if field_node.getElementsByTagName('None'): value = None else: value = field.to_python(getInnerText(field_node).strip()) data[field.name] = value obj = base.build_instance(Model, data, self.db) # Return a DeserializedObject so that the m2m data has a place to live. return base.DeserializedObject(obj, m2m_data)
def __next__(self): d = self.data_it.__next__() # Look up the model using the model loading mechanism. model_path = None try: model_path = self.model_path_from_data(d) model_class = self.get_model_class(model_path) except base.DeserializationError: if self.ignore: return self.__next__() else: raise # Start building a data dictionary from the object. data = {} pk = self.get_pk_from_data(d) if (pk): try: data[model_class._meta.pk.attname] = self.pk_to_python(model_class, pk) except Exception as e: raise base.DeserializationError.WithData(e, model_path, pk, None) if model_class not in self.field_names_cache: self.field_names_cache[model_class] = self.field_names(model_class) field_names = self.field_names_cache[model_class] # Handle each field for (field_name, field_value) in self.fields_from_data(d).items(): if self.ignore and field_name not in field_names: continue field = model_class._meta.get_field(field_name) # Do not handle relation fields. if(self.field_is_nonrelational(self.ignore, model_class, field)): try: data[field.name] = field.to_python(field_value) except Exception as e: raise base.DeserializationError("{}: ({}:pk={}) field:'{}': field_value:'{}'".format( e, model_path, pk, field_name, field_value )) obj = base.build_instance(model_class, data, self.db) return base.DeserializedObject(obj)
def handle_row(self, row): model_name = row.get('model') try: model = apps.get_model(model_name) except (KeyError, LookupError): if not self.ignore: raise base_serializer.DeserializationError( "Invalid model identifier: '{}'".format(model_name) ) data = {} pk = row.get('pk') try: data[model._meta.pk.attname] = model._meta.pk.to_python(pk) except Exception as e: raise base_serializer.DeserializationError.WithData( e, model_name, pk, None, ) real_fieldnames = [field.name for field in model._meta.get_fields()] for column_name in self.only_fieldnames: if column_name not in real_fieldnames and self.ignore: continue m2m_data = {} value = row[column_name] value = force_text(value, settings.DEFAULT_CHARSET, strings_only=True) field = model._meta.get_field(column_name) try: data[field.name] = field.to_python(value) except Exception as e: raise base_serializer.DeserializationError.WithData( e, model, pk, value ) data obj = base_serializer.build_instance(model, data, self.db) return base_serializer.DeserializedObject(obj, m2m_data)
def __next__(self): if self.current_row < self.num_objects + 3: values = {} for ix in range(self.num_fields): values[self.fields[ix][0]] = self.get_value( self.ws[self.current_row][ix], self.fields[ix][1]) present = datetime.now() # The following is not necessary since we are saving the object using it's save method # However, it doesn't hurt for af in self.auto_now_fields: if af.name not in values or values[af.name] is None: values[af.name] = present obj = base.build_instance(self.Model, values, False) self.current_row += 1 obj.save() return base.DeserializedObject(obj, {}) raise StopIteration
def read_object(obj, **attrs): if not isinstance(obj, dict): values = obj.getchildren() obj = dict(obj.attrib) else: values = obj['children'] if 'fields' not in obj: obj['fields'] = {} for child in values: if child.tag == 'field': if 'ref' in child.attrib: obj['fields'][child.attrib['name']] = Object.get_object( child.attrib['ref']).object_id elif 'model' in child.attrib: obj['fields'][child.attrib['name']] = ContentType.objects.only( 'pk').get_by_natural_key( *child.attrib['model'].split('.')).pk else: s = child.text if 'translate' in child.attrib: s = _(s) obj['fields'][child.attrib['name']] = s obj_name = obj.pop('id') obj_id = None try: print('Load object', obj_name) obj_id = Object.objects.get(name=obj_name) instance = obj_id.content_object for k, v in obj['fields'].items(): setattr(instance, k, v) instance.save() except ObjectDoesNotExist: instance = base.build_instance(_get_model(obj['model']), obj['fields'], attrs.get('using', DEFAULT_DB_ALIAS)) instance.save() ct = ContentType.objects.get_by_natural_key( instance._meta.app_label, instance._meta.model_name.lower()) obj_id = Object.objects.create(name=obj_name, object_id=instance.pk, content_type=ct) return instance
def read_object(obj, **attrs): if not isinstance(obj, dict): values = obj.getchildren() obj = dict(obj.attrib) else: values = obj['children'] if 'fields' not in obj: obj['fields'] = {} for child in values: if child.tag == 'field': if 'ref' in child.attrib: obj['fields'][child.attrib['name']] = Object.get_object(child.attrib['ref']).object_id elif 'model' in child.attrib: obj['fields'][child.attrib['name']] = ContentType.objects.only('pk').get_by_natural_key(*child.attrib['model'].split('.')).pk else: s = child.text if 'translate' in child.attrib: s = _(s) obj['fields'][child.attrib['name']] = s obj_name = obj.pop('id') obj_id = None try: obj_id = Object.objects.get(name=obj_name) instance = obj_id.content_object for k, v in obj['fields'].items(): setattr(instance, k, v) instance.save() except ObjectDoesNotExist: instance = base.build_instance(_get_model(obj['model']), obj['fields'], attrs.get('using', DEFAULT_DB_ALIAS)) instance.save() ct = ContentType.objects.get_by_natural_key(instance._meta.app_label, instance._meta.model_name.lower()) obj_id = Object.objects.create( name=obj_name, object_id=instance.pk, content_type=ct ) return instance
def _handle_object(self, node): """Convert an <object> node to a DeserializedObject.""" # Look up the model using the model loading mechanism. If this fails, # bail. model_path = node.getAttribute("model") model_class = self.get_model_class(model_path) # Start building a data dictionary from the object. data = {} if node.hasAttribute('pk'): data[model_class._meta.pk.attname] = self.pk_to_python(model_class, node.getAttribute('pk')) field_names = self.field_names(model_class) # Deserialize each field. for field_node in node.getElementsByTagName("field"): # If the field is missing the name attribute, bail field_name = field_node.getAttribute("name") if not field_name: raise base.DeserializationError("<field> node is missing the 'name' attribute") # Get the field from the Model. This will raise a # FieldDoesNotExist if, well, the field doesn't exist, which will # be propagated correctly unless ignorenonexistent=True is used. if self.ignore and field_name not in field_names: continue field = model_class._meta.get_field(field_name) # Do not handle relation fields. if(self.field_is_nonrelational(self.ignore, model_class, field)): if field_node.getElementsByTagName('None'): value = None else: value = field.to_python(getInnerText(field_node).strip()) data[field.name] = value obj = base.build_instance(model_class, data, self.db) return base.DeserializedObject(obj)
def Deserializer(json, using=DEFAULT_DB_ALIAS, **options): # TODO: fix """ Deserialize JSON back into Django ORM instances. Django deserializers yield a DeserializedObject generator. DeserializedObjects are thin wrappers over POPOs. """ m2m_data = {} # Generate the serializer ModelDeserializer = ConceptSerializerFactory().generate_deserializer(json) # Instantiate the serializer data = JSON.loads(json) Model = apps.get_model(data['serialized_model']) # Deserialize the data serializer = ModelDeserializer(data=data) serializer.is_valid(raise_exception=True) obj = build_instance(Model, data, using) yield DeserializedObject(obj, m2m_data)
def Deserializer(object_list, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ db = options.pop('using', DEFAULT_DB_ALIAS) ignore = options.pop('ignorenonexistent', False) models.get_apps() for d in object_list: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) data = {} if 'pk' in d: data[Model._meta.pk.attname] = Model._meta.pk.to_python( d.get("pk", None)) m2m_data = {} model_fields = Model._meta.get_all_field_names() # Handle each field for (field_name, field_value) in six.iteritems(d["fields"]): if ignore and field_name not in model_fields: # skip fields no longer on model continue if isinstance(field_value, str): field_value = smart_text(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True) field = Model._meta.get_field(field_name) # Handle M2M relations if field.rel and isinstance(field.rel, models.ManyToManyRel): if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): def m2m_convert(value): if hasattr(value, '__iter__') and not isinstance( value, six.text_type): return field.rel.to._default_manager.db_manager( db).get_by_natural_key(*value).pk else: return smart_text( field.rel.to._meta.pk.to_python(value)) else: m2m_convert = lambda v: smart_text( field.rel.to._meta.pk.to_python(v)) m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] # Handle FK fields elif field.rel and isinstance(field.rel, models.ManyToOneRel): if field_value is not None: if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): if hasattr(field_value, '__iter__') and not isinstance( field_value, six.text_type): obj = field.rel.to._default_manager.db_manager( db).get_by_natural_key(*field_value) value = getattr(obj, field.rel.field_name) # If this is a natural foreign key to an object that # has a FK/O2O as the foreign key, use the FK value if field.rel.to._meta.pk.rel: value = value.pk else: value = field.rel.to._meta.get_field( field.rel.field_name).to_python(field_value) data[field.attname] = value else: data[field.attname] = field.rel.to._meta.get_field( field.rel.field_name).to_python(field_value) else: data[field.attname] = None # Handle all other fields else: data[field.name] = field.to_python(field_value) obj = base.build_instance(Model, data, db) yield base.DeserializedObject(obj, m2m_data)
def Deserializer(object_list, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ db = options.pop('using', DEFAULT_DB_ALIAS) ignore = options.pop('ignorenonexistent', False) field_names_cache = {} # Model: <list of field_names> for d in object_list: # Look up the model and starting build a dict of data for it. try: Model = _get_model(d["model"]) except base.DeserializationError: if ignore: continue else: raise data = {} if 'pk' in d: try: data[Model._meta.pk.attname] = Model._meta.pk.to_python(d.get('pk')) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), None) m2m_data = {} if Model not in field_names_cache: field_names_cache[Model] = {f.name for f in Model._meta.get_fields()} field_names = field_names_cache[Model] # Handle each field for (field_name, field_value) in d["fields"].items(): if ignore and field_name not in field_names: # skip fields no longer on model continue if isinstance(field_value, str): field_value = force_text( field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True ) field = Model._meta.get_field(field_name) # Handle M2M relations if field.remote_field and isinstance(field.remote_field, models.ManyToManyRel): model = field.remote_field.model if hasattr(model._default_manager, 'get_by_natural_key'): def m2m_convert(value): if hasattr(value, '__iter__') and not isinstance(value, str): return model._default_manager.db_manager(db).get_by_natural_key(*value).pk else: return force_text(model._meta.pk.to_python(value), strings_only=True) else: def m2m_convert(v): return force_text(model._meta.pk.to_python(v), strings_only=True) try: m2m_data[field.name] = [] for pk in field_value: m2m_data[field.name].append(m2m_convert(pk)) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), pk) # Handle FK fields elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel): model = field.remote_field.model if field_value is not None: try: default_manager = model._default_manager field_name = field.remote_field.field_name if hasattr(default_manager, 'get_by_natural_key'): if hasattr(field_value, '__iter__') and not isinstance(field_value, str): obj = default_manager.db_manager(db).get_by_natural_key(*field_value) value = getattr(obj, field.remote_field.field_name) # If this is a natural foreign key to an object that # has a FK/O2O as the foreign key, use the FK value if model._meta.pk.remote_field: value = value.pk else: value = model._meta.get_field(field_name).to_python(field_value) data[field.attname] = value else: data[field.attname] = model._meta.get_field(field_name).to_python(field_value) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) else: data[field.attname] = None # Handle all other fields else: try: data[field.name] = field.to_python(field_value) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) obj = base.build_instance(Model, data, db) yield base.DeserializedObject(obj, m2m_data)
def Deserializer(object_list, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ # Too bad this is so big, we only add a tiny bit of code # near the beginning and end; but not such that we can just wrap it. from django.conf import settings from django.core.serializers import python _get_model = python._get_model db = options.pop('using', DEFAULT_DB_ALIAS) models.get_apps() for d in object_list: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) data = {} if 'pk' in d: data[Model._meta.pk.attname] = Model._meta.pk.to_python(d['pk']) m2m_data = {} # Handle each field for (field_name, field_value) in d["fields"].iteritems(): if isinstance(field_value, str): field_value = smart_unicode(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True) field = Model._meta.get_field(field_name) # Handle M2M relations if field.rel and isinstance(field.rel, models.ManyToManyRel): if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): def m2m_convert(value): if hasattr(value, '__iter__'): return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk else: return smart_unicode(field.rel.to._meta.pk.to_python(value)) else: m2m_convert = lambda v: smart_unicode(field.rel.to._meta.pk.to_python(v)) m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] # Handle FK fields elif field.rel and isinstance(field.rel, models.ManyToOneRel): if field_value is not None: if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): if hasattr(field_value, '__iter__'): obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value) value = getattr(obj, field.rel.field_name) # If this is a natural foreign key to an object that # has a FK/O2O as the foreign key, use the FK value if field.rel.to._meta.pk.rel: value = value.pk else: value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) data[field.attname] = value else: data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) else: data[field.attname] = None # Handle all other fields else: data[field.name] = field.to_python(field_value) obj = base.build_instance(Model, data, db) yield base.DeserializedObject(obj, m2m_data)
def Deserializer(object_list, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ db = options.pop('using', DEFAULT_DB_ALIAS) ignore = options.pop('ignorenonexistent', False) app_cache.populate() for d in object_list: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) data = {} if 'pk' in d: data[Model._meta.pk.attname] = Model._meta.pk.to_python(d.get("pk", None)) m2m_data = {} model_fields = Model._meta.get_all_field_names() # Handle each field for (field_name, field_value) in six.iteritems(d["fields"]): if ignore and field_name not in model_fields: # skip fields no longer on model continue if isinstance(field_value, str): field_value = smart_text(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True) field = Model._meta.get_field(field_name) # Handle M2M relations if field.rel and isinstance(field.rel, models.ManyToManyRel): if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): def m2m_convert(value): if hasattr(value, '__iter__') and not isinstance(value, six.text_type): return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk else: return smart_text(field.rel.to._meta.pk.to_python(value)) else: m2m_convert = lambda v: smart_text(field.rel.to._meta.pk.to_python(v)) m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] # Handle FK fields elif field.rel and isinstance(field.rel, models.ManyToOneRel): if field_value is not None: if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type): obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value) value = getattr(obj, field.rel.field_name) # If this is a natural foreign key to an object that # has a FK/O2O as the foreign key, use the FK value if field.rel.to._meta.pk.rel: value = value.pk else: value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) data[field.attname] = value else: data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) else: data[field.attname] = None # Handle all other fields else: data[field.name] = field.to_python(field_value) obj = base.build_instance(Model, data, db) yield base.DeserializedObject(obj, m2m_data)
def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ handle_forward_references = options.pop("handle_forward_references", False) field_names_cache = {} # Model: <list of field_names> for d in object_list: # Look up the model and starting build a dict of data for it. try: Model = _get_model(d["model"]) except base.DeserializationError: if ignorenonexistent: continue else: raise data = {} if "pk" in d: try: data[Model._meta.pk.attname] = Model._meta.pk.to_python( d.get("pk")) except Exception as e: raise base.DeserializationError.WithData( e, d["model"], d.get("pk"), None) m2m_data = {} deferred_fields = {} if Model not in field_names_cache: field_names_cache[Model] = { f.name for f in Model._meta.get_fields() } field_names = field_names_cache[Model] # Handle each field for (field_name, field_value) in d["fields"].items(): if ignorenonexistent and field_name not in field_names: # skip fields no longer on model continue field = Model._meta.get_field(field_name) # Handle M2M relations if field.remote_field and isinstance(field.remote_field, models.ManyToManyRel): try: values = base.deserialize_m2m_values( field, field_value, using, handle_forward_references) except base.M2MDeserializationError as e: raise base.DeserializationError.WithData( e.original_exc, d["model"], d.get("pk"), e.pk) if values == base.DEFER_FIELD: deferred_fields[field] = field_value else: m2m_data[field.name] = values # Handle FK fields elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel): try: value = base.deserialize_fk_value( field, field_value, using, handle_forward_references) except Exception as e: raise base.DeserializationError.WithData( e, d["model"], d.get("pk"), field_value) if value == base.DEFER_FIELD: deferred_fields[field] = field_value else: data[field.attname] = value # Handle all other fields else: try: data[field.name] = field.to_python(field_value) except Exception as e: raise base.DeserializationError.WithData( e, d["model"], d.get("pk"), field_value) obj = base.build_instance(Model, data, using) yield base.DeserializedObject(obj, m2m_data, deferred_fields)
def Deserializer(object_list, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ # Too bad this is so big, we only add a tiny bit of code # near the beginning and end; but not such that we can just wrap it. from django.conf import settings from django.core.serializers import python _get_model = python._get_model db = options.pop('using', DEFAULT_DB_ALIAS) models.get_apps() for d in object_list: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) data = {} if 'pk' in d: data[Model._meta.pk.attname] = Model._meta.pk.to_python(d['pk']) m2m_data = {} # Handle each field for (field_name, field_value) in d["fields"].iteritems(): if isinstance(field_value, str): field_value = smart_unicode(field_value, options.get( "encoding", settings.DEFAULT_CHARSET), strings_only=True) field = Model._meta.get_field(field_name) # Handle M2M relations if field.rel and isinstance(field.rel, models.ManyToManyRel): if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): def m2m_convert(value): if hasattr(value, '__iter__'): return field.rel.to._default_manager.db_manager( db).get_by_natural_key(*value).pk else: return smart_unicode( field.rel.to._meta.pk.to_python(value)) else: m2m_convert = lambda v: smart_unicode( field.rel.to._meta.pk.to_python(v)) m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] # Handle FK fields elif field.rel and isinstance(field.rel, models.ManyToOneRel): if field_value is not None: if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): if hasattr(field_value, '__iter__'): obj = field.rel.to._default_manager.db_manager( db).get_by_natural_key(*field_value) value = getattr(obj, field.rel.field_name) # If this is a natural foreign key to an object that # has a FK/O2O as the foreign key, use the FK value if field.rel.to._meta.pk.rel: value = value.pk else: value = field.rel.to._meta.get_field( field.rel.field_name).to_python(field_value) data[field.attname] = value else: data[field.attname] = field.rel.to._meta.get_field( field.rel.field_name).to_python(field_value) else: data[field.attname] = None # Handle all other fields else: data[field.name] = field.to_python(field_value) obj = base.build_instance(Model, data, db) yield base.DeserializedObject(obj, m2m_data)
def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False, **options): """ Deserialize simple Python objects back into Django ORM instances. It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ field_names_cache = {} # Model: <list of field_names> for d in object_list: # Look up the model and starting build a dict of data for it. try: Model = _get_model(d["model"]) except base.DeserializationError: if ignorenonexistent: continue else: raise data = {} if 'pk' in d: try: data[Model._meta.pk.attname] = Model._meta.pk.to_python(d.get('pk')) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), None) m2m_data = {} if Model not in field_names_cache: field_names_cache[Model] = {f.name for f in Model._meta.get_fields()} field_names = field_names_cache[Model] # Handle each field for (field_name, field_value) in d["fields"].items(): if ignorenonexistent and field_name not in field_names: # skip fields no longer on model continue field = Model._meta.get_field(field_name) # Handle M2M relations if field.remote_field and isinstance(field.remote_field, models.ManyToManyRel): try: values = base.deserialize_m2m_values(field, field_value, using) except base.M2MDeserializationError as e: raise base.DeserializationError.WithData(e.original_exc, d['model'], d.get('pk'), e.pk) m2m_data[field.name] = values # Handle FK fields elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel): try: value = base.deserialize_fk_value(field, field_value, using) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) data[field.attname] = value # Handle all other fields else: try: data[field.name] = field.to_python(field_value) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) obj = base.build_instance(Model, data, using) yield base.DeserializedObject(obj, m2m_data)
"""
else: data[field.attname] = model._meta.get_field(field_name).to_python(field_value) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) else: data[field.attname] = None # Handle all other fields else: try: data[field.name] = field.to_python(field_value) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) <<<<<<< HEAD obj = base.build_instance(Model, data, db) ======= obj = base.build_instance(Model, data, using) >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 yield base.DeserializedObject(obj, m2m_data) def _get_model(model_identifier): <<<<<<< HEAD """ Helper to look up a model from an "app_label.model_name" string. """ ======= """Look up a model from an "app_label.model_name" string.""" >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 try: