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

ModelSelect2Widget broken for empty fields in 7.6.0 #29

Closed
mikemanger opened this issue Jan 14, 2021 · 2 comments
Closed

ModelSelect2Widget broken for empty fields in 7.6.0 #29

mikemanger opened this issue Jan 14, 2021 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@mikemanger
Copy link

mikemanger commented Jan 14, 2021

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.

@mikemanger mikemanger added the bug Something isn't working label Jan 14, 2021
@codingjoe
Copy link
Owner

Good catch, yes, we should filter on an empty search term. I'll create a patch.

@codingjoe
Copy link
Owner

Patch was released in 7.6.1 🎉

Thanks again @mikemanger

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants