Skip to content

ModelSelect2Widget broken for empty fields in 7.6.0 #29

Closed
@mikemanger

Description

@mikemanger

Describe the bug
I have a widget that lets me search models related to another model. It worked as expected in 7.5.0, but is causing a 500 error in 7.6.0 when expanding the select2 (searching with an empty string should just show the first x results I think). I think it is because a check for empty strings was removed in #26.

Exception & Traceback

Internal Server Error: /premises/select2_flock_lookup/auto.json
Traceback (most recent call last):
  File "C:\Path\env\lib\site-packages\django\db\models\fields\__init__.py", line 1774, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: ''

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "C:\Path\env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Path\env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Path\env\lib\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Path\env\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Path\env\lib\site-packages\django_select2\views.py", line 37, in get
    self.object_list = self.get_queryset()
  File "C:\Path\premises\views.py", line 153, in get_queryset
    cached_queryset = super().get_queryset()
  File "C:\Path\env\lib\site-packages\django_select2\views.py", line 57, in get_queryset
    return self.widget.filter_queryset(
  File "C:\Path\env\lib\site-packages\django_select2\forms.py", line 414, in filter_queryset
    return queryset.filter(select).distinct()
  File "C:\Path\env\lib\site-packages\django\db\models\query.py", line 942, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Path\env\lib\site-packages\django\db\models\query.py", line 962, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, *args, **kwargs)
  File "C:\Path\env\lib\site-packages\django\db\models\query.py", line 969, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "C:\Path\env\lib\site-packages\django\db\models\sql\query.py", line 1358, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Path\env\lib\site-packages\django\db\models\sql\query.py", line 1377, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "C:\Path\env\lib\site-packages\django\db\models\sql\query.py", line 1237, in build_filter
    return self._add_q(
  File "C:\Path\env\lib\site-packages\django\db\models\sql\query.py", line 1377, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "C:\Path\env\lib\site-packages\django\db\models\sql\query.py", line 1319, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Path\env\lib\site-packages\django\db\models\sql\query.py", line 1165, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\Path\env\lib\site-packages\django\db\models\lookups.py", line 24, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\Path\env\lib\site-packages\django\db\models\lookups.py", line 76, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "C:\Path\env\lib\site-packages\django\db\models\fields\__init__.py", line 1776, in get_prep_value
    raise e.__class__(
ValueError: Field 'house_number' expected a number but got ''.

Code Snippet

# widgets.py
class HouseSelectWidget(ModelSelect2Widget):
    """Used in forms to search for houses"""
    model = House
    search_fields = [
        'house_number',
    ]

    def __init__(self, attrs=None, choices=(), **kwargs):
        if 'data_view' not in kwargs:
            kwargs['data_view'] = 'premises:select2_house_lookup'
        super().__init__(attrs=None, choices=(), **kwargs)

    def build_attrs(self, base_attrs, extra_attrs=None):
        self.attrs.setdefault('data-minimum-input-length', 0)
        return super().build_attrs(base_attrs, extra_attrs)

# views.py
class HouseAutoResponseView(AutoResponseView):
    """
    Used by select2 for filtering by subscriber.
    """
    def get_queryset(self):
        cached_queryset = super().get_queryset()
        # code that filters the queryset by current user
        return cached_queryset

To Reproduce
This is using Django 3.1.5 with Python 3.8.7 on Windows and also tested on Linux with the same config.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions