def generate_data(self, field):
     "Get a unique and valid data for the field."
     config = self._field_fixture_factory(field.__class__)
     is_supported_field = config != None
     if is_supported_field:
         key = get_unique_field_name(field)
         data = eval('self.%s(field, "%s")' % (config, key,))
     else:
         if field.null:
             data = None # a workaround for versatility
         else:
             raise UnsupportedFieldError(get_unique_field_name(field)), None, sys.exc_info()[2]
     return data
Example #2
0
    def set_data_for_a_field(self,
                             model_class,
                             __instance,
                             __field,
                             persist_dependencies=True,
                             **kwargs):
        if __field.name in kwargs:
            config = kwargs[__field.name]
            try:
                data = self._process_field_with_customized_fixture(
                    __instance, __field, config, persist_dependencies)
            except PendingField:
                return  # ignore this field for a while.
            except Exception as e:
                six.reraise(
                    InvalidConfigurationError,
                    InvalidConfigurationError(get_unique_field_name(__field),
                                              e),
                    sys.exc_info()[2])
        else:
            data = self._process_field_with_default_fixture(
                __field, model_class, persist_dependencies)

        if is_file_field(__field) and data:
            django_file = data
            if isinstance(django_file, File):
                setattr(__instance, __field.name,
                        data.name)  # set the attribute
                if hasattr(django_file.file,
                           'mode') and django_file.file.mode != 'rb':
                    django_file.file.close(
                    )  # this file may be open in another mode, for example, in a+b
                    opened_file = open(
                        django_file.file.name,
                        'rb')  # to save the file it must be open in rb mode
                    django_file.file = opened_file  # we update the reference to the rb mode opened file

                # https://github.com/paulocheque/django-dynamic-fixture/issues/10
                # getattr(__instance, __field.name).save(django_file.name, django_file) # save the file into the file storage system
                # django_file.close()
                getattr(__instance, __field.name).save(django_file.name,
                                                       django_file,
                                                       save=False)

            else:  # string (saving just a name in the file, without saving the file to the storage file system
                setattr(__instance, __field.name, data)  # Model.field = data
        else:
            if self.debug_mode:
                LOGGER.debug(
                    '%s.%s = %s' %
                    (get_unique_model_name(model_class), __field.name, data))
            try:
                setattr(__instance, __field.name, data)  # Model.field = data
            except ValueError as e:
                if is_relationship_field(__field):
                    setattr(__instance, "%s_id" % __field.name,
                            data)  # Model.field = data
                else:
                    six.reraise(*sys.exc_info())
        self.fields_processed.append(__field.name)
 def new(self, model_class, shelve=False, named_shelve=None, persist_dependencies=True, **kwargs):
     """
     Create an instance filled with data without persist it.
     1) validate all kwargs match Model.fields.
     2) validate model is a model.Model class.
     3) Iterate model fields: for each field, fill it with data.
     @shelve: the current configuration will be stored in the DDF library. It can be True or a string (named shelve).
     @named_shelve: restore configuration saved in DDF library with a name.
     @persist_dependencies: tell if internal dependencies will be saved in the database or not.
     """
     if self.debug_mode:
         LOGGER.debug('>>> [%s] Generating instance.' % get_unique_model_name(model_class))
     configuration = self._configure_params(model_class, shelve, named_shelve, **kwargs)
     instance = model_class()
     if not is_model_class(instance):
         raise InvalidModelError(get_unique_model_name(model_class)), None, sys.exc_info()[2]
     for field in get_fields_from_model(model_class):
         if is_key_field(field) and 'id' not in configuration: continue
         if field.name in self.ignore_fields: continue
         self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
     number_of_pending_fields = len(self.pending_fields)
     # For Copier fixtures: dealing with pending fields that need to receive values of another fields.
     i = 0
     while self.pending_fields != []:
         field_name = self.pending_fields.pop(0)
         field = get_field_by_name_or_raise(model_class, field_name)
         self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
         i += 1
         if i > 2 * number_of_pending_fields: # dealing with infinite loop too.
             raise InvalidConfigurationError(get_unique_field_name(field), u'Cyclic dependency of Copiers.'), None, sys.exc_info()[2]
     if self.debug_mode:
         LOGGER.debug('<<< [%s] Instance created.' % get_unique_model_name(model_class))
     return instance
Example #4
0
    def new(self, model_class, shelve=False, named_shelve=None, persist_dependencies=True, **kwargs):
        """
        Create an instance filled with data without persist it.
        1) validate all kwargs match Model.fields.
        2) validate model is a model.Model class.
        3) Iterate model fields: for each field, fill it with data.

        :shelve: the current configuration will be stored in the DDF library. It can be True or a string (named shelve).
        :named_shelve: restore configuration saved in DDF library with a name.
        :persist_dependencies: tell if internal dependencies will be saved in the database or not.
        """
        if self.debug_mode:
            LOGGER.debug('>>> [%s] Generating instance.' % get_unique_model_name(model_class))
        configuration = self._configure_params(model_class, shelve, named_shelve, **kwargs)
        instance = model_class()
        if not is_model_class(instance):
            raise InvalidModelError(get_unique_model_name(model_class))
        for field in get_fields_from_model(model_class):
            if is_key_field(field) and 'id' not in configuration: continue
            if field.name not in self.kwargs and self._is_ignored_field(field.name): continue
            self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
        number_of_pending_fields = len(self.pending_fields)
        # For Copier fixtures: dealing with pending fields that need to receive values of another fields.
        i = 0
        while self.pending_fields != []:
            field_name = self.pending_fields.pop(0)
            field = get_field_by_name_or_raise(model_class, field_name)
            self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
            i += 1
            if i > 2 * number_of_pending_fields: # dealing with infinite loop too.
                raise InvalidConfigurationError(get_unique_field_name(field), 'Cyclic dependency of Copiers.')
        if self.debug_mode:
            LOGGER.debug('<<< [%s] Instance created.' % get_unique_model_name(model_class))
        return instance
    def set_data_for_a_field(self, model_class, instance, field, persist_dependencies=True, **kwargs):
        if field.name in kwargs:
            config = kwargs[field.name]
            try:
                data = self._process_field_with_customized_fixture(instance, field, config, persist_dependencies)
            except PendingField:
                return # ignore this field for a while.
            except Exception as e:
                raise InvalidConfigurationError(get_unique_field_name(field), e), None, sys.exc_info()[2]
        else:
            data = self._process_field_with_default_fixture(field, model_class, persist_dependencies)

        if is_file_field(field) and data:
            django_file = data
            if isinstance(django_file, File):
                setattr(instance, field.name, data.name) # set the attribute
                if django_file.file.mode != 'rb':
                    django_file.file.close() # this file may be open in another mode, for example, in a+b
                    opened_file = open(django_file.file.name, 'rb') # to save the file it must be open in rb mode
                    django_file.file = opened_file # we update the reference to the rb mode opened file
                getattr(instance, field.name).save(django_file.name, django_file) # save the file into the file storage system
                django_file.close()
            else: # string (saving just a name in the file, without saving the file to the storage file system
                setattr(instance, field.name, data) # Model.field = data
        else:
            if self.debug_mode:
                LOGGER.debug('%s.%s = %s' % (get_unique_model_name(model_class), field.name, data))
            setattr(instance, field.name, data) # Model.field = data
        self.fields_processed.append(field.name)
Example #6
0
 def generate_data(self, field):
     "Get a unique and valid data for the field."
     config = self._field_fixture_factory(field.__class__)
     is_supported_field = config != None
     if is_supported_field:
         key = get_unique_field_name(field)
         data = eval('self.%s(field, "%s")' % (
             config,
             key,
         ))
     else:
         if field.null:
             data = None  # a workaround for versatility
         else:
             raise (UnsupportedFieldError(get_unique_field_name(field)))
     return data
Example #7
0
 def generate_data(self, field):
     "Get a unique and valid data for the field."
     field_fullname = field.__module__ + "." + field.__class__.__name__
     fixture = self.plugins.get(field_fullname, {})
     if type(fixture) == dict:
         fixture = fixture.get('ddf_fixture', None)
     if fixture and callable(fixture):
         return fixture()
     config = self._field_fixture_factory(field.__class__)
     is_supported_field = config != None
     if is_supported_field:
         key = get_unique_field_name(field)
         data = eval('self.%s(field, "%s")' % (config, key,))
     else:
         if field.null:
             data = None # a workaround for versatility
         else:
             raise(UnsupportedFieldError(get_unique_field_name(field)))
     return data
Example #8
0
 def generate_data(self, field):
     "Get a unique and valid data for the field."
     field_fullname = field.__module__ + "." + field.__class__.__name__
     fixture = self.plugins.get(field_fullname, {})
     if type(fixture) == dict:
         fixture = fixture.get('ddf_fixture', None)
     if fixture and callable(fixture):
         return fixture()
     config = self._field_fixture_factory(field.__class__)
     is_supported_field = config != None
     if is_supported_field:
         key = get_unique_field_name(field)
         data = eval('self.%s(field, "%s")' % (config, key,))
     else:
         if field.null:
             data = None # a workaround for versatility
         else:
             raise(UnsupportedFieldError(get_unique_field_name(field) + ' (%s)' % (field_fullname)))
     return data
Example #9
0
    def get(self, model_class, shelve=False, named_shelve=None, **kwargs):
        """
        Create an instance with data and persist it.

        :shelve: the current configuration will be stored in the DDF library.
        :named_shelve: restore configuration saved in DDF library with a name.
        """
        instance = self.new(model_class,
                            shelve=shelve,
                            named_shelve=named_shelve,
                            **kwargs)
        if is_model_abstract(model_class):
            raise InvalidModelError(get_unique_model_name(model_class))
        try:
            if self.validate_models:
                instance.full_clean()
            if model_class in _PRE_SAVE:
                try:
                    _PRE_SAVE[model_class](instance)
                except Exception as e:
                    six.reraise(InvalidReceiverError, InvalidReceiverError(e),
                                sys.exc_info()[2])
            self._save_the_instance(instance)
            if model_class in _POST_SAVE:
                try:
                    _POST_SAVE[model_class](instance)
                except Exception as e:
                    six.reraise(InvalidReceiverError, InvalidReceiverError(e),
                                sys.exc_info()[2])
        except Exception as e:
            if self.print_errors:
                print_field_values(instance)
            six.reraise(BadDataError,
                        BadDataError(get_unique_model_name(model_class), e),
                        sys.exc_info()[2])
        self.fields_processed = []  # TODO: need more tests for M2M and Copier
        self.pending_fields = []
        for field in get_many_to_many_fields_from_model(model_class):
            if field.name in kwargs.keys():  # TODO: library
                manytomany_field = getattr(instance, field.name)
                fixture = kwargs[field.name]
                try:
                    self._process_many_to_many_field(field, manytomany_field,
                                                     fixture, instance)
                except InvalidManyToManyConfigurationError as e:
                    six.reraise(InvalidManyToManyConfigurationError, e,
                                sys.exc_info()[2])
                except Exception as e:
                    six.reraise(
                        InvalidManyToManyConfigurationError,
                        InvalidManyToManyConfigurationError(
                            get_unique_field_name(field), e),
                        sys.exc_info()[2])
        return instance
Example #10
0
 def _configure_params(self, model_class, shelve, named_shelve, **kwargs):
     """
     1) validate kwargs
     2) load default fixture from DDF library. Store default fixture in DDF library.
     3) Load fixtures defined in F attributes.
     """
     if self.validate_args:
         self._validate_kwargs(model_class, kwargs)
     library = DDFLibrary.get_instance()
     if shelve:  # shelving before use_library property: do not twist two different configurations (anti-pattern)
         for field_name in kwargs.keys():
             if field_name in self._DDF_CONFIGS:
                 continue
             field = get_field_by_name_or_raise(model_class, field_name)
             fixture = kwargs[field_name]
             if field.unique and not (isinstance(
                     fixture, (DynamicFixture, Copier, DataFixture))
                                      or callable(fixture)):
                 raise InvalidConfigurationError(
                     'It is not possible to store static values for fields with unique=True (%s)'
                     % get_unique_field_name(field))
         library.add_configuration(model_class, kwargs, name=shelve)
     if self.use_library:
         # load ddf_setup.py of the model application
         app_name = get_app_name_of_model(model_class)
         if app_name not in _LOADED_DDF_SETUP_MODULES:
             full_module_name = '%s.tests.ddf_setup' % app_name
             try:
                 _LOADED_DDF_SETUP_MODULES.append(app_name)
                 import_module(full_module_name)
             except ImportError:
                 pass  # ignoring if module does not exist
             except Exception as e:
                 six.reraise(InvalidDDFSetupError, InvalidDDFSetupError(e),
                             sys.exc_info()[2])
         configuration_default = library.get_configuration(
             model_class, name=DDFLibrary.DEFAULT_KEY)
         configuration_custom = library.get_configuration(model_class,
                                                          name=named_shelve)
         configuration = {}
         configuration.update(
             configuration_default)  # always use default configuration
         configuration.update(
             configuration_custom)  # override default configuration
         configuration.update(
             kwargs
         )  # override shelved configuration with current configuration
     else:
         configuration = kwargs
     configuration.update(
         self.kwargs
     )  # Used by F: kwargs are passed by constructor, not by get.
     return configuration
Example #11
0
 def teach(self, model_class, ddf_lesson=None, **kwargs):
     library = DDFLibrary.get_instance()
     for field_name in kwargs.keys():
         if field_name in self._DDF_CONFIGS:
             continue
         field = get_field_by_name_or_raise(model_class, field_name)
         fixture = kwargs[field_name]
         if field.unique and not (isinstance(
                 fixture,
             (DynamicFixture, Copier, DataFixture)) or callable(fixture)):
             raise InvalidConfigurationError(
                 'It is not possible to store static values for fields with unique=True (%s). Try using a lambda function instead.'
                 % get_unique_field_name(field))
     library.add_configuration(model_class, kwargs, name=ddf_lesson)
Example #12
0
    def get(self, model_class, ddf_lesson=None, **kwargs):
        '''
        Create an instance with data and persist it.

        :ddf_lesson: a custom lesson that will be used to create the model object.
        '''
        instance = self.new(model_class, ddf_lesson=ddf_lesson, **kwargs)
        if is_model_abstract(model_class):
            raise InvalidModelError(get_unique_model_name(model_class))
        try:
            if self.validate_models:
                instance.full_clean()
            if model_class in _PRE_SAVE:
                try:
                    _PRE_SAVE[model_class](instance)
                except Exception as e:
                    six.reraise(InvalidReceiverError, InvalidReceiverError(e),
                                sys.exc_info()[2])
            self._save_the_instance(instance)
            if model_class in _POST_SAVE:
                try:
                    _POST_SAVE[model_class](instance)
                except Exception as e:
                    six.reraise(InvalidReceiverError, InvalidReceiverError(e),
                                sys.exc_info()[2])
        except Exception as e:
            if self.print_errors:
                print_field_values(instance)
            six.reraise(BadDataError,
                        BadDataError(get_unique_model_name(model_class), e),
                        sys.exc_info()[2])
        self.fields_processed = []  # TODO: need more tests for M2M and Copier
        self.pending_fields = []
        for field in get_many_to_many_fields_from_model(model_class):
            if field.name in kwargs.keys():  # TODO: library
                manytomany_field = getattr(instance, field.name)
                fixture = kwargs[field.name]
                try:
                    self._process_many_to_many_field(field, manytomany_field,
                                                     fixture, instance)
                except InvalidManyToManyConfigurationError as e:
                    six.reraise(InvalidManyToManyConfigurationError, e,
                                sys.exc_info()[2])
                except Exception as e:
                    six.reraise(
                        InvalidManyToManyConfigurationError,
                        InvalidManyToManyConfigurationError(
                            get_unique_field_name(field), e),
                        sys.exc_info()[2])
        return instance
Example #13
0
    def set_data_for_a_field(self,
                             model_class,
                             instance,
                             field,
                             persist_dependencies=True,
                             **kwargs):
        if field.name in kwargs:
            config = kwargs[field.name]
            try:
                data = self._process_field_with_customized_fixture(
                    instance, field, config, persist_dependencies)
            except PendingField:
                return  # ignore this field for a while.
            except Exception as e:
                six.reraise(
                    InvalidConfigurationError,
                    InvalidConfigurationError(get_unique_field_name(field), e),
                    sys.exc_info()[2])
        else:
            data = self._process_field_with_default_fixture(
                field, model_class, persist_dependencies)

        if is_file_field(field) and data:
            django_file = data
            if isinstance(django_file, File):
                setattr(instance, field.name, data.name)  # set the attribute
                if django_file.file.mode != 'rb':
                    django_file.file.close(
                    )  # this file may be open in another mode, for example, in a+b
                    opened_file = open(
                        django_file.file.name,
                        'rb')  # to save the file it must be open in rb mode
                    django_file.file = opened_file  # we update the reference to the rb mode opened file
                getattr(instance, field.name).save(
                    django_file.name,
                    django_file)  # save the file into the file storage system
                django_file.close()
            else:  # string (saving just a name in the file, without saving the file to the storage file system
                setattr(instance, field.name, data)  # Model.field = data
        else:
            if self.debug_mode:
                LOGGER.debug(
                    '%s.%s = %s' %
                    (get_unique_model_name(model_class), field.name, data))
            setattr(instance, field.name, data)  # Model.field = data
        self.fields_processed.append(field.name)
Example #14
0
    def get(self, model_class, shelve=False, named_shelve=None, **kwargs):
        """
        Create an instance with data and persist it.

        :shelve: the current configuration will be stored in the DDF library.
        :named_shelve: restore configuration saved in DDF library with a name.
        """
        instance = self.new(model_class, shelve=shelve, named_shelve=named_shelve, **kwargs)
        if is_model_abstract(model_class):
            raise InvalidModelError(get_unique_model_name(model_class)), None, sys.exc_info()[2]
        try:
            if self.validate_models:
                instance.full_clean()
            if model_class in _PRE_SAVE:
                try:
                    _PRE_SAVE[model_class](instance)
                except Exception as e:
                    raise InvalidReceiverError(e), None, sys.exc_info()[2]
            self._save_the_instance(instance)
            if model_class in _POST_SAVE:
                try:
                    _POST_SAVE[model_class](instance)
                except Exception as e:
                    raise InvalidReceiverError(e), None, sys.exc_info()[2]
        except Exception as e:
            if self.print_errors:
                print_field_values(instance)
            raise BadDataError(get_unique_model_name(model_class), e), None, sys.exc_info()[2]
        self.fields_processed = [] # TODO: need more tests for M2M and Copier
        self.pending_fields = []
        for field in get_many_to_many_fields_from_model(model_class):
            if field.name in kwargs.keys(): # TODO: library
                manytomany_field = getattr(instance, field.name)
                fixture = kwargs[field.name]
                try:
                    self._process_many_to_many_field(field, manytomany_field, fixture, instance)
                except InvalidManyToManyConfigurationError as e:
                    raise e, None, sys.exc_info()[2]
                except Exception as e:
                    raise InvalidManyToManyConfigurationError(get_unique_field_name(field), e), None, sys.exc_info()[2]
        return instance
Example #15
0
    def set_data_for_a_field(self, model_class, __instance, __field, persist_dependencies=True, **kwargs):
        if __field.name in kwargs:
            config = kwargs[__field.name]
            try:
                data = self._process_field_with_customized_fixture(__instance, __field, config, persist_dependencies)
            except PendingField:
                return # ignore this field for a while.
            except Exception as e:
                six.reraise(InvalidConfigurationError, InvalidConfigurationError(get_unique_field_name(__field), e), sys.exc_info()[2])
        else:
            data = self._process_field_with_default_fixture(__field, model_class, persist_dependencies)

        if is_file_field(__field) and data:
            django_file = data
            if isinstance(django_file, File):
                setattr(__instance, __field.name, data.name) # set the attribute
                if hasattr(django_file.file, 'mode') and django_file.file.mode != 'rb':
                    django_file.file.close() # this file may be open in another mode, for example, in a+b
                    opened_file = open(django_file.file.name, 'rb') # to save the file it must be open in rb mode
                    django_file.file = opened_file # we update the reference to the rb mode opened file

                # https://github.com/paulocheque/django-dynamic-fixture/issues/10
                # getattr(__instance, __field.name).save(django_file.name, django_file) # save the file into the file storage system
                # django_file.close()
                getattr(__instance, __field.name).save(django_file.name, django_file, save=False)

            else: # string (saving just a name in the file, without saving the file to the storage file system
                setattr(__instance, __field.name, data) # Model.field = data
        else:
            if self.debug_mode:
                LOGGER.debug('%s.%s = %s' % (get_unique_model_name(model_class), __field.name, data))
            try:
                setattr(__instance, __field.name, data) # Model.field = data
            except ValueError as e:
                if is_relationship_field(__field):
                    setattr(__instance, "%s_id" % __field.name, data) # Model.field = data
                else:
                    six.reraise(*sys.exc_info())
        self.fields_processed.append(__field.name)
Example #16
0
 def _configure_params(self, model_class, shelve, named_shelve, **kwargs):
     """
     1) validate kwargs
     2) load default fixture from DDF library. Store default fixture in DDF library.
     3) Load fixtures defined in F attributes.
     """
     if self.validate_args:
         self._validate_kwargs(model_class, kwargs)
     library = DDFLibrary.get_instance()
     if shelve: # shelving before use_library property: do not twist two different configurations (anti-pattern)
         for field_name in kwargs.keys():
             if field_name in self._DDF_CONFIGS:
                 continue
             field = get_field_by_name_or_raise(model_class, field_name)
             fixture = kwargs[field_name]
             if field.unique and not (isinstance(fixture, (DynamicFixture, Copier, DataFixture)) or callable(fixture)):
                 raise InvalidConfigurationError('It is not possible to store static values for fields with unique=True (%s)' % get_unique_field_name(field))
         library.add_configuration(model_class, kwargs, name=shelve)
     if self.use_library:
         # load ddf_setup.py of the model application
         app_name = get_app_name_of_model(model_class)
         if app_name not in _LOADED_DDF_SETUP_MODULES:
             full_module_name = '%s.tests.ddf_setup' % app_name
             try:
                 _LOADED_DDF_SETUP_MODULES.append(app_name)
                 import_module(full_module_name)
             except ImportError:
                 pass # ignoring if module does not exist
             except Exception as e:
                 raise InvalidDDFSetupError(e), None, sys.exc_info()[2]
         configuration_default = library.get_configuration(model_class, name=DDFLibrary.DEFAULT_KEY)
         configuration_custom = library.get_configuration(model_class, name=named_shelve)
         configuration = {}
         configuration.update(configuration_default) # always use default configuration
         configuration.update(configuration_custom) # override default configuration
         configuration.update(kwargs) # override shelved configuration with current configuration
     else:
         configuration = kwargs
     configuration.update(self.kwargs) # Used by F: kwargs are passed by constructor, not by get.
     return configuration
Example #17
0
    def get(self, model_class, shelve=False, named_shelve=None, **kwargs):
        """
        Create an instance with data and persist it.

        :shelve: the current configuration will be stored in the DDF library.
        :named_shelve: restore configuration saved in DDF library with a name.
        """
        if 'locators' in kwargs:
            locators = kwargs.pop('locators')
        else:
            locators = []
        if len(kwargs) > 0 and locators == [] and _get_instance_by_args(model_class, **kwargs) != None:
            ret = _get_instance_by_args(model_class, **kwargs)
            return ret
        elif locators: 
            # we need to be sure that we havent build something meeting the locators yet.
            ret = self._check_against_db(model_class, locators, **kwargs)
            if ret:
                return ret

        if(model_class in get_created_classes() and model_class not in ALLOW_MULTIPLE):
            return get_instance_by_class(model_class)

        instance = self.new(model_class, locators, shelve=shelve, named_shelve=named_shelve, **kwargs)
        if is_model_abstract(model_class):
            raise InvalidModelError(get_unique_model_name(model_class))
        try:
            if self.validate_models:
                instance.full_clean()
            if model_class in _PRE_SAVE:
                try:
                    _PRE_SAVE[model_class](instance)
                except Exception as e:
                    six.reraise(InvalidReceiverError, InvalidReceiverError(e), sys.exc_info()[2])
            instance = self._save_the_instance(instance)
            created_instances.add(instance)

            if model_class in _POST_SAVE:
                try:
                    _POST_SAVE[model_class](instance)
                except Exception as e:
                    six.reraise(InvalidReceiverError, InvalidReceiverError(e), sys.exc_info()[2])
        except Exception as e:
            if self.print_errors:
                print_field_values(instance)
            six.reraise(BadDataError, BadDataError(get_unique_model_name(model_class), e), sys.exc_info()[2])
        self.fields_processed = [] # TODO: need more tests for M2M and Copier
        self.pending_fields = []
        for field in get_many_to_many_fields_from_model(model_class):
            if field.name in kwargs.keys(): # TODO: library
                manytomany_field = getattr(instance, field.name)
                fixture = kwargs[field.name]
                try:
                    self._process_many_to_many_field(field, manytomany_field, fixture, instance)
                except InvalidManyToManyConfigurationError as e:
                    six.reraise(InvalidManyToManyConfigurationError, e, sys.exc_info()[2])
                except Exception as e:
                    six.reraise(InvalidManyToManyConfigurationError, InvalidManyToManyConfigurationError(get_unique_field_name(field), e), sys.exc_info()[2])
        return instance
Example #18
0
    def new(self,
            model_class,
            ddf_lesson=None,
            persist_dependencies=True,
            **kwargs):
        '''
        Create an instance filled with data without persist it.
        1) validate all kwargs match Model.fields.
        2) validate model is a model.Model class.
        3) Iterate model fields: for each field, fill it with data.

        :ddf_lesson: the lesson that will be used to create the model instance, if exists.
        :persist_dependencies: tell if internal dependencies will be saved in the database or not.
        '''
        if self.debug_mode:
            LOGGER.debug('>>> [%s] Generating instance.' %
                         get_unique_model_name(model_class))
        configuration = self._configure_params(model_class, ddf_lesson,
                                               **kwargs)
        instance = model_class()
        if not is_model_class(instance):
            raise InvalidModelError(get_unique_model_name(model_class))

        try:
            # https://github.com/paulocheque/django-dynamic-fixture/pull/112
            from polymorphic import PolymorphicModel
            is_polymorphic = isinstance(instance, PolymorphicModel)
        except ImportError:
            # Django-polymorphic is not installed so the model can't be polymorphic.
            is_polymorphic = False
        for field in get_fields_from_model(model_class):
            if is_key_field(field) and field.name not in configuration:
                continue
            if field.name not in self.kwargs and self._is_ignored_field(
                    field.name):
                continue
            if is_polymorphic and (field.name == 'polymorphic_ctype'
                                   or field.primary_key):
                continue
            self.set_data_for_a_field(
                model_class,
                instance,
                field,
                persist_dependencies=persist_dependencies,
                **configuration)
        number_of_pending_fields = len(self.pending_fields)
        # For Copier fixtures: dealing with pending fields that need to receive values of another fields.
        i = 0
        while self.pending_fields != []:
            field_name = self.pending_fields.pop(0)
            field = get_field_by_name_or_raise(model_class, field_name)
            self.set_data_for_a_field(
                model_class,
                instance,
                field,
                persist_dependencies=persist_dependencies,
                **configuration)
            i += 1
            if i > 2 * number_of_pending_fields:  # dealing with infinite loop too.
                raise InvalidConfigurationError(
                    get_unique_field_name(field),
                    'Cyclic dependency of Copiers.')
        if self.debug_mode:
            LOGGER.debug('<<< [%s] Instance created.' %
                         get_unique_model_name(model_class))
        return instance