Beispiel #1
0
    def process_m2m(self, instance, field):
        # check django's version number to determine how intermediary models
        # are checked if they are auto created or not.
        auto_created_through_model = False
        through = get_remote_field(field).through
        auto_created_through_model = through._meta.auto_created

        if auto_created_through_model:
            return self.process_field(instance, field, is_m2m=True)
        # if m2m relation has intermediary model:
        #   * only generate relation if 'generate_m2m' is given
        #   * first generate intermediary model and assign a newly created
        #     related model to the foreignkey
        kwargs = {}
        if field.name in self.generate_m2m:
            # get fk to related model on intermediary model
            related_fks = [fk
                for fk in through._meta.fields
                if isinstance(fk, related.ForeignKey) and \
                    get_remote_field_to(fk) is get_remote_field_to(field)]
            self_fks = [fk
                for fk in through._meta.fields
                if isinstance(fk, related.ForeignKey) and \
                    get_remote_field_to(fk) is self.model]
            assert len(related_fks) == 1
            assert len(self_fks) == 1
            related_fk = related_fks[0]
            self_fk = self_fks[0]
            min_count, max_count = self.generate_m2m[field.name]
            intermediary_model = generators.MultipleInstanceGenerator(
                AutoFixture(through,
                            field_values={
                                self_fk.name:
                                instance,
                                related_fk.name:
                                generators.InstanceGenerator(
                                    autofixture.get(
                                        get_remote_field_to(field)))
                            }),
                min_count=min_count,
                max_count=max_count,
                **kwargs).generate()
    def process_m2m(self, instance, field):
        # check django's version number to determine how intermediary models
        # are checked if they are auto created or not.
        auto_created_through_model = False
        through = get_remote_field(field).through
        auto_created_through_model = through._meta.auto_created

        if auto_created_through_model:
            return self.process_field(instance, field)
        # if m2m relation has intermediary model:
        #   * only generate relation if 'generate_m2m' is given
        #   * first generate intermediary model and assign a newly created
        #     related model to the foreignkey
        kwargs = {}
        if field.name in self.generate_m2m:
            # get fk to related model on intermediary model
            related_fks = [fk
                for fk in through._meta.fields
                if isinstance(fk, related.ForeignKey) and \
                    get_remote_field_to(fk) is get_remote_field_to(field)]
            self_fks = [fk
                for fk in through._meta.fields
                if isinstance(fk, related.ForeignKey) and \
                    get_remote_field_to(fk) is self.model]
            assert len(related_fks) == 1
            assert len(self_fks) == 1
            related_fk = related_fks[0]
            self_fk = self_fks[0]
            min_count, max_count = self.generate_m2m[field.name]
            intermediary_model = generators.MultipleInstanceGenerator(
                AutoFixture(
                    through,
                    field_values={
                        self_fk.name: instance,
                        related_fk.name: generators.InstanceGenerator(
                            autofixture.get(get_remote_field_to(field)))
                    }),
                min_count=min_count,
                max_count=max_count,
                **kwargs).generate()
Beispiel #3
0
    def get_generator(self, field):
        '''
        Return a value generator based on the field instance that is passed to
        this method. This function may return ``None`` which means that the
        specified field will be ignored (e.g. if no matching generator was
        found).
        '''
        if isinstance(field, fields.AutoField):
            return None
        if self.is_inheritance_parent(field):
            return None
        if (
            field.default is not fields.NOT_PROVIDED and
            not self.overwrite_defaults and
            field.name not in self.field_values):
                return None
        kwargs = {}

        if field.name in self.field_values:
            value = self.field_values[field.name]
            if isinstance(value, generators.Generator):
                return value
            elif isinstance(value, AutoFixture):
                return generators.InstanceGenerator(autofixture=value)
            elif callable(value):
                return generators.CallableGenerator(value=value)
            return generators.StaticGenerator(value=value)

        if field.null:
            kwargs['empty_p'] = self.none_p
        if field.choices:
            return generators.ChoicesGenerator(choices=field.choices, **kwargs)
        if isinstance(field, related.ForeignKey):
            # if generate_fk is set, follow_fk is ignored.
            is_self_fk = (get_remote_field_to(field)().__class__ == self.model)
            if field.name in self.generate_fk and not is_self_fk:
                return generators.InstanceGenerator(
                    autofixture.get(
                        get_remote_field_to(field),
                        follow_fk=self.follow_fk.get_deep_links(field.name),
                        generate_fk=self.generate_fk.get_deep_links(field.name)),
                    limit_choices_to=get_remote_field(field).limit_choices_to)
            if field.name in self.follow_fk:
                selected = generators.InstanceSelector(
                    get_remote_field_to(field),
                    limit_choices_to=get_remote_field(field).limit_choices_to)
                if selected.get_value() is not None:
                    return selected
            if field.blank or field.null:
                return generators.NoneGenerator()
            if is_self_fk and not field.null:
                raise CreateInstanceError(
                    u'Cannot resolve self referencing field "%s" to "%s" without null=True' % (
                        field.name,
                        '%s.%s' % (
                            get_remote_field_to(field)._meta.app_label,
                            get_remote_field_to(field)._meta.object_name,
                        )
                ))
            raise CreateInstanceError(
                u'Cannot resolve ForeignKey "%s" to "%s". Provide either '
                u'"follow_fk" or "generate_fk" parameters.' % (
                    field.name,
                    '%s.%s' % (
                        get_remote_field_to(field)._meta.app_label,
                        get_remote_field_to(field)._meta.object_name,
                    )
            ))
        if isinstance(field, related.ManyToManyField):
            if field.name in self.generate_m2m:
                min_count, max_count = self.generate_m2m[field.name]
                return generators.MultipleInstanceGenerator(
                    autofixture.get(get_remote_field_to(field)),
                    limit_choices_to=get_remote_field(field).limit_choices_to,
                    min_count=min_count,
                    max_count=max_count,
                    **kwargs)
            if field.name in self.follow_m2m:
                min_count, max_count = self.follow_m2m[field.name]
                return generators.InstanceSelector(
                    get_remote_field_to(field),
                    limit_choices_to=get_remote_field(field).limit_choices_to,
                    min_count=min_count,
                    max_count=max_count,
                    **kwargs)
            if field.blank or field.null:
                return generators.StaticGenerator([])
            raise CreateInstanceError(
                u'Cannot assign instances of "%s" to ManyToManyField "%s". '
                u'Provide either "follow_m2m" or "generate_m2m" argument.' % (
                    '%s.%s' % (
                        get_remote_field_to(field)._meta.app_label,
                        get_remote_field_to(field)._meta.object_name,
                    ),
                    field.name,
            ))
        if isinstance(field, fields.FilePathField):
            return generators.FilePathGenerator(
                path=field.path, match=field.match, recursive=field.recursive,
                max_length=field.max_length, **kwargs)
        if isinstance(field, fields.CharField):
            if isinstance(field, fields.SlugField):
                generator = generators.SlugGenerator
            elif isinstance(field, fields.EmailField):
                return generators.EmailGenerator(
                    max_length=min(field.max_length, 30))
            elif isinstance(field, fields.URLField):
                return generators.URLGenerator(
                    max_length=min(field.max_length, 25))
            elif field.max_length > 15:
                return generators.LoremSentenceGenerator(
                    common=False,
                    max_length=field.max_length)
            else:
                generator = generators.StringGenerator
            return generator(max_length=field.max_length)
        if isinstance(field, fields.DecimalField):
            return generators.DecimalGenerator(
                decimal_places=field.decimal_places,
                max_digits=field.max_digits)
        if hasattr(fields, 'BigIntegerField'):
            if isinstance(field, fields.BigIntegerField):
                return generators.IntegerGenerator(
                    min_value=-field.MAX_BIGINT - 1,
                    max_value=field.MAX_BIGINT,
                    **kwargs)
        if isinstance(field, ImageField):
            return generators.ImageGenerator(storage=field.storage, **kwargs)
        for field_class, generator in self.field_to_generator.items():
            if isinstance(field, field_class):
                return generator(**kwargs)
        return None