Reputation: 2434
I've implemented django-autocomplete-light and django-filter together for two fields (foreign keys referencing related fields in two other models:
field__field = ModelMultipleChoiceFilter(queryset=Model.objects.all(),
widget=autocomplete.ModelSelect2Multiple(url='url'))
field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
widget=autocomplete.ModelSelect2Multiple(url='url2'))
When I try to use DAL's forward
ability...
field__field = ModelMultipleChoiceFilter(queryset=Model.objects.all(),
widget=autocomplete.ModelSelect2Multiple(url='url'))
field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
widget=autocomplete.ModelSelect2Multiple(url='url2', forward=['field__field']))
...nothing happens. The autocomplete boxes do not cascade.
I think it might have to do with the fact that django-filter requires the queryset to be called explicitly.
How do I implement forward
effectively?
Edit:
views.py
class FieldAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = Model.objects.all()
if self.q:
qs = qs.filter(field__icontains=self.q)
return qs
class Field2Autocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = SecondModel.objects.all()
field = self.forwarded.get('field', None)
if field:
qs = qs.filter(field=field)
if self.q:
qs = qs.filter(field2__icontains=self.q)
return qs
In addition to the views, I also use Field
to allow for the related name...
field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
widget=autocomplete.ModelSelect2Multiple(url='url2', forward=(Field('field_field', 'field')))
...but this results in 'Field' object is not iterable
. Here is the traceback:
Traceback:
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\core\handlers\exception.py" in inner
41. response = get_response(request)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\core\handlers\base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\core\handlers\base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\username\repos\mysite\alerts\views.py" in search
79. return render(request, 'search.html', context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\shortcuts.py" in render
30. content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\loader.py" in render_to_string
68. return template.render(context, request)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\backends\django.py" in render
66. return self.template.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render
207. return self._render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in _render
199. return self.nodelist.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render
990. bit = node.render_annotated(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render_annotated
957. return self.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\loader_tags.py" in render
177. return compiled_parent._render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in _render
199. return self.nodelist.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render
990. bit = node.render_annotated(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render_annotated
957. return self.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\loader_tags.py" in render
72. result = block.nodelist.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render
990. bit = node.render_annotated(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render_annotated
957. return self.render(context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render
1046. return render_value_in_context(output, context)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\template\base.py" in render_value_in_context
1024. value = force_text(value)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\utils\encoding.py" in force_text
76. s = six.text_type(s)
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\utils\html.py" in <lambda>
385. klass.__str__ = lambda self: mark_safe(klass_str(self))
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\forms\boundfield.py" in __str__
41. return self.as_widget()
File "C:\Users\username\python\envs\mysite\lib\site-packages\django\forms\boundfield.py" in as_widget
127. **kwargs
File "C:\Users\username\python\envs\mysite\lib\site-packages\dal\widgets.py" in render
151. conf = self.render_forward_conf(attrs['id'])
File "C:\Users\username\python\envs\mysite\lib\site-packages\dal\widgets.py" in render_forward_conf
96. ) + \
Exception Type: TypeError at /search
Exception Value: 'Field' object is not iterable
The view setup works for autocomplete on a form (it forwards properly). But when I try to use it as a widget to a filter, it doesn't work.
Upvotes: 0
Views: 1839
Reputation: 108
I had the 'Field' object is not iterable
error and it has an easy solution. The 'forward' argument expects a tuple, but declared as in your code is just a Field object. So, the solution is this:
field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
widget=autocomplete.ModelSelect2Multiple(url='url2', forward=(Field('field_field', 'field'),)))
Note the comma which makes the difference between object and tuple.
Upvotes: 1