mlavin / django-selectable

Tools and widgets for using/creating auto-complete selection widgets using Django and jQuery UI.
http://django-selectable.readthedocs.io/en/latest/
BSD 2-Clause "Simplified" License
129 stars 64 forks source link

ValidationError from ModelLookup #211

Open silverdrake11 opened 4 years ago

silverdrake11 commented 4 years ago

Nones appear in the autocomplete if a previously selelected option has been filtered out. This causes a ValidationError when making an update to the data in (even if you select another option)

When using the filters option in the ModelLookup, get_item() only checks the filtered results, causing the Nones.

This is my code:

class ScheduleLookup(ModelLookup):
    model = Schedule
    search_fields = ['topic__startswith', 'topic__icontains']
    filters = {'active': True}

Steps to recreate: 1) Enable django selectable in django admin for Model A 2) Have a model A point to model B 3) Filter out model B 4) Since model A still points to model B, observe the None that shows up 5) Try to change the None to any other value, validation error results as seen here

Traceback (most recent call last):
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/contrib/admin/options.py", line 551, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/contrib/admin/sites.py", line 224, in inner
    return view(request, *args, **kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/reversion/admin.py", line 163, in change_view
    return super(VersionAdmin, self).change_view(request, object_id, form_url, extra_context)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/contrib/admin/options.py", line 1511, in change_view
    return self.changeform_view(request, object_id, form_url, extra_context)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/utils/decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/utils/decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/contrib/admin/options.py", line 1408, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/contrib/admin/options.py", line 1447, in _changeform_view
    if all_valid(formsets) and form_validated:
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/forms/formsets.py", line 460, in all_valid
    if not formset.is_valid():
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/forms/formsets.py", line 321, in is_valid
    self.errors
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/forms/formsets.py", line 295, in errors
    self.full_clean()
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/forms/formsets.py", line 345, in full_clean
    if not form.has_changed():
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/forms/forms.py", line 439, in has_changed
    return bool(self.changed_data)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/django/forms/forms.py", line 461, in changed_data
    if field.has_changed(initial_value, data_value):
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/selectable/forms/fields.py", line 35, in has_changed
    initial = self.to_python(initial)
  File "/base/data/home/apps/s~test-cec-concierge/v1-2-11-533-g1d4045c.425185308766234968/site-packages/selectable/forms/fields.py", line 87, in to_python
    raise ValidationError(self.error_messages['invalid_choice'])
ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
silverdrake11 commented 4 years ago

Pull request above, checks the entire model and not the just the queryset