def action_generate(self, data): """ Метод обработчик действия generate. Данное действие отвечает за сохранение всех корректных данных, полученных и проверенных на этапе валидации. Для получения объектов моделей используется встроенный десериализатор, используемый в команде loaddata (так как он умеет только создавать объекты, а не обновлять их, используется несколько более сложный механизм вызова метода save у модели, нежели в десериализаторе). После добавления объектов в базу данных, pk новых объектов сохранаются в массиве и используются в дальнейшем при обработке нижестоящих в иерархии коллекций. """ serialized = self.get_serialized_data(data) prepared = self.prepare_serialized_data(serialized) # lazy deserialized = Deserializer(prepared) # lazy self.log("\ngenerate %s " % str(len(serialized)).ljust(5)) for dobj, sobj in zip(deserialized, serialized): # lazy if not self.require_to_save_object(dobj, sobj): sobj['source']['pk'] = dobj.object.pk char = '-' else: obj = self.get_deserialized_object(dobj, sobj) obj = self.save_deserialized_object(obj, dobj, sobj) sobj['source']['pk'] = obj.pk char = '+' if getattr(obj, '__is_new__', False) else '.' self.log(char) # clear query log db.reset_queries()
def save_record(self, data, pk=None): if pk: # If we are updating an existing record existing_record = self.get_record(pk) existing_record['fields'].update(data) save_data = [existing_record] else: # If we are creating a new record data['uuid'] = str(uuid4()) save_data = [{ 'fields': data, 'model': '{}.{}'.format(self.model._meta.app_label, self.model._meta.model_name), }] for obj in Deserializer(save_data): obj.save()
def _test_json_field_after_serialization(serialized): for obj in Deserializer([serialized]): self.assertIsInstance(obj.object.auth_context, dict)
def create(self, request): objects_in_fixture = 0 loaded_objects_count = 0 models = set() fixture = request.data.get('fixture') if fixture: with transaction.atomic(): connection = connections[DEFAULT_DB_ALIAS] with connection.constraint_checks_disabled(): objects = Deserializer(fixture, ignorenonexistent=True, handle_forward_references=True) objs_with_deferred_fields = [] for obj in objects: objects_in_fixture += 1 if router.allow_migrate_model(DEFAULT_DB_ALIAS, obj.object.__class__): loaded_objects_count += 1 models.add(obj.object.__class__) try: obj.save() # psycopg2 raises ValueError if data contains NUL chars. except (DatabaseError, IntegrityError, ValueError) as e: e.args = ( "Could not load %(app_label)s.%(object_name)s(pk=%(pk)s): %(error_msg)s" % { 'app_label': obj.object._meta.app_label, 'object_name': obj.object._meta.object_name, 'pk': obj.object.pk, 'error_msg': e, }, ) raise if obj.deferred_fields: objs_with_deferred_fields.append(obj) for obj in objs_with_deferred_fields: obj.save_deferred_fields() if loaded_objects_count > 0: sequence_sql = connection.ops.sequence_reset_sql( no_style(), models) if sequence_sql: with connection.cursor() as cursor: for line in sequence_sql: cursor.execute(line) # Close the DB connection -- unless we're still in a transaction. This # is required as a workaround for an edge case in MySQL: if the same # connection is used to create tables, load data, and query, the query # can return incorrect results. See Django #7572, MySQL #37735. if transaction.get_autocommit(): connections[DEFAULT_DB_ALIAS].close() return Response({"objects_loaded": loaded_objects_count}, status=status.HTTP_200_OK)