Example #1
0
    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, {})
Example #3
0
    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)
Example #4
0
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)
Example #5
0
    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)
Example #6
0
    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
Example #8
0
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
Example #9
0
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
Example #10
0
    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)
Example #11
0
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)
Example #12
0
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)
Example #13
0
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)
Example #14
0
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)
Example #15
0
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)
Example #16
0
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)
Example #17
0
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)
Example #18
0
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)
"""
Example #20
0
                        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:
Example #21
0
"""