Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIG mistake in Field.clean method #431

Closed
liminspace opened this issue Apr 2, 2016 · 2 comments
Closed

BIG mistake in Field.clean method #431

liminspace opened this issue Apr 2, 2016 · 2 comments

Comments

@liminspace
Copy link

There is code:

if not value and self.default != NOT_PROVIDED:
    if callable(self.default):
        return self.default()
    return self.default

WTF guys? Why if not value you will set default? o_O
If self.default is 1 and value is 0 it is OK! Why you going to change value if it is NOT BOOL(VALUE)?
I have problem with this strange logic all time.
How you can use this library with this mistake?
Why nobody can't fix this stupid mistake???

@liminspace
Copy link
Author

My fast solution (with other solutions):

from import_export import resources, fields, widgets
from django.contrib.contenttypes.models import ContentType

class IEField(fields.Field):
    def clean(self, data):
        try:
            value = data[self.column_name]
        except KeyError:
            raise KeyError("Column '%s' not found in dataset. Available "
                           "columns are: %s" % (self.column_name,
                                                list(data.keys())))

        try:
            value = self.widget.clean(value)
        except ValueError as e:
            raise ValueError("Column '%s': %s" % (self.column_name, e))

        return value


class IEModelResource(resources.ModelResource):
    @classmethod
    def field_from_django_field(self, field_name, django_field, readonly):
        FieldWidget = self.widget_from_django_field(django_field)
        widget_kwargs = self.widget_kwargs_for_field(field_name)
        field = IEField(
            attribute=field_name,
            column_name=field_name,
            widget=FieldWidget(**widget_kwargs),
            readonly=readonly,
            default=django_field.default,
        )
        return field


class FloatNullWidget(widgets.NumberWidget):
    def clean(self, value):
        if self.is_empty(value) or value in ('None', ''):
            return None
        return float(str(value).replace(',', '.'))


class ContentTypeWidget(widgets.Widget):
    def clean(self, value):
        return ContentType.objects.get_by_natural_key(*value.split('.'))

    def render(self, value):
        return '{}.{}'.format(value.app_label, value.model)

Use IEField instead fields.Field
Use IEModelResource instead resources.ModelResource
Use ContentTypeWidget for content type field:

class MyResource(IEModelResource):
    content_type = IEField(attribute='content_type', widget=ContentTypeWidget())

    class Meta:
        model = MyModel
        fields = ('id', 'content_type', 'object_id', 'lang', 'text')
        export_order = fields
        skip_unchanged = True
        report_skipped = False
        use_transactions = True

    def get_queryset(self):
        qs = super(MyResource, self).get_queryset()
        return qs.select_related('content_type').order_by('pk')

Use FloatNullWidget for float field with null=True:

lat = IEField(attribute='lat', widget=FloatNullWidget())

@bmihelac
Copy link
Member

bmihelac commented Apr 2, 2016

Hey @liminspace, I think that your language is inappropriate so please stop using it. We are committed to providing a friendly, safe and welcoming environment for all.

Regarding this issue, there is some discussion in #364

I would gladly accept pull request that fixes this issue.

bmihelac added a commit that referenced this issue Apr 6, 2016
Field constructor `default` argument is NOT_PROVIDED instead of None
Field clean method checks value against `Field.empty_values` [None, '']
@bmihelac bmihelac closed this as completed Apr 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants