示例#1
0
    def get_field_meta(self, field: models.Field) -> OrderedDict:
        # check if we need to override default get_field_meta behaviour
        get_field_meta = getattr(self, 'get_%s_field_meta' % field.name, None)
        if callable(get_field_meta):
            return get_field_meta(field, self.obj)

        sentinel = object()
        d = OrderedDict()

        for attr in self.attr_list:
            val = getattr(field, attr, sentinel)
            if val is sentinel:
                continue
            if attr in ['max_length']:
                if val is None:
                    continue

            if attr in ['verbose_name']:
                val = force_text(val)

            d[attr] = val

        d['type'] = field.get_internal_type()
        d['required'] = self.is_required(field)
        if field.default != models.NOT_PROVIDED:
            if callable(field.default):
                d['default'] = field.default()
            else:
                d['default'] = field.default
        if hasattr(field, 'choices') and field.choices:
            d['choices'] = list(self.format_choices(field))

        if field.related_model:
            if field.name not in self.no_data:
                user_url_getter = getattr(self, 'get_%s_dataset_url' % field.name.lower(), None)
                if callable(user_url_getter):
                    d['data'] = user_url_getter(field, self.obj)
                elif field.name in self.dataset_urls:
                    d['data'] = force_text(self.dataset_urls[field.name])
                else:
                    d['data'] = self.get_field_related_data(field)

        data_update = self.update_fields.get(field.name, {})
        d.update(data_update)

        # check if we need to perform runtime update
        update_field_meta_callback = getattr(self, 'update_%s_field_meta' % field.name, None)
        if callable(update_field_meta_callback):
            d.update(update_field_meta_callback(field, self.obj))

        return d
示例#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)