Esempio n. 1
0
    def __init__(self, target: models.Field):
        default = self.NO_DEFAULT
        if target.has_default():
            if isinstance(target.get_default(), Enum):
                default = target.get_default().value
            else:
                default = target.get_default()

        choices = None
        if target.choices:
            choices = []
            for value, label in target.choices:
                choices.append(label)

        super().__init__(name=target.name,
                         type=self.define_representation_type(target),
                         description=target.help_text,
                         default=default,
                         is_required=self.check_is_required(target),
                         choices=choices)
        if self.type is Attribute.TYPE.OBJECT:
            if isinstance(target, (models.OneToOneField, models.ForeignKey)):
                self.type_of = target.related_model
            else:
                raise NotImplementedError()
        if self.type is Attribute.TYPE.ARRAY:
            self.type_of = target.related_model
        if self.type is Attribute.TYPE.FILE:
            self.type = Attribute.TYPE.STRING
        self.target = target
Esempio n. 2
0
    def generate_value(self, field: Field, commit: bool = True) -> Any:
        """Call the associated generator with a field passing all required args.

        Generator Resolution Precedence Order:
        -- `field.default` - model field default value, unless explicitly overwritten during baking
        -- `attr_mapping` - mapping per attribute name
        -- `choices` -- mapping from available field choices
        -- `type_mapping` - mapping from user defined type associated generators
        -- `default_mapping` - mapping from pre-defined type associated
           generators

        `attr_mapping` and `type_mapping` can be defined easily overwriting the
        model.
        """
        is_content_type_fk = isinstance(field, ForeignKey) and issubclass(
            self._remote_field(field).model, contenttypes.models.ContentType)
        # we only use default unless the field is overwritten in `self.rel_fields`
        if field.has_default() and field.name not in self.rel_fields:
            if callable(field.default):
                return field.default()
            return field.default
        elif field.name in self.attr_mapping:
            generator = self.attr_mapping[field.name]
        elif getattr(field, "choices"):
            generator = random_gen.gen_from_choices(field.choices)
        elif is_content_type_fk:
            generator = self.type_mapping[contenttypes.models.ContentType]
        elif generators.get(field.__class__):
            generator = generators.get(field.__class__)
        elif field.__class__ in self.type_mapping:
            generator = self.type_mapping[field.__class__]
        else:
            raise TypeError("%s is not supported by baker." % field.__class__)

        # attributes like max_length, decimal_places are taken into account when
        # generating the value.
        field._using = self._using
        generator_attrs = get_required_values(generator, field)

        if field.name in self.rel_fields:
            generator_attrs.update(
                filter_rel_attrs(field.name, **self.rel_attrs))

        if not commit:
            generator = getattr(generator, "prepare", generator)

        return generator(**generator_attrs)
Esempio n. 3
0
    def _skip_field(self, field: Field) -> bool:
        from django.contrib.contenttypes.fields import GenericRelation

        # check for fill optional argument
        if isinstance(self.fill_in_optional, bool):
            field.fill_optional = self.fill_in_optional
        else:
            field.fill_optional = field.name in self.fill_in_optional

        if isinstance(field, FileField) and not self.create_files:
            return True

        # Don't Skip related _id fields defined in the iterator attributes
        if ((isinstance(field, OneToOneField) or isinstance(field, ForeignKey))
                and hasattr(field, "attname")
                and field.attname in self.iterator_attrs):
            return False

        # Skip links to parent so parent is not created twice.
        if isinstance(field,
                      OneToOneField) and self._remote_field(field).parent_link:
            return True

        if isinstance(field, (AutoField, GenericRelation, OrderWrt)):
            return True

        if all([
                field.name not in self.model_attrs,
                field.name not in self.rel_fields,
                field.name not in self.attr_mapping,
        ]):
            # Django is quirky in that BooleanFields are always "blank",
            # but have no default.
            if not field.fill_optional and (
                    not issubclass(field.__class__, Field)
                    or field.has_default() or
                (field.blank and not isinstance(field, BooleanField))):
                return True

        if field.name not in self.model_attrs:
            if field.name not in self.rel_fields and (field.null and
                                                      not field.fill_optional):
                return True

        return False