django-autocomplete-light和django-filter正向滤波器选择

时间:2017-09-08 14:51:35

标签: python django django-filter django-autocomplete-light

我已经为两个字段实现了django-autocomplete-light和django-filter(在其他两个模型中引用相关字段的外键:

field__field = ModelMultipleChoiceFilter(queryset=Model.objects.all(),
              widget=autocomplete.ModelSelect2Multiple(url='url'))

field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
                  widget=autocomplete.ModelSelect2Multiple(url='url2'))

当我尝试使用DAL的forward能力......

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']))

......没有任何反应。自动填充框不会级联。

我认为这可能与django-filter要求显式调用queryset这一事实有关。

如何有效实施forward

修改

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

除了视图,我还使用Field来允许相关名称......

field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
                      widget=autocomplete.ModelSelect2Multiple(url='url2', forward=(Field('field_field', 'field')))

...但这导致'Field' object is not iterable。这是追溯:

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

视图设置适用于表单上的自动填充(正确转发)。但是当我尝试将它用作过滤器的小部件时,它不起作用。

1 个答案:

答案 0 :(得分:1)

我遇到了'Field' object is not iterable错误,它有一个简单的解决方案。 'forward'参数需要一个元组,但在代码中声明只是一个Field对象。所以,解决方案是:

field2__field2 = ModelMultipleChoiceFilter(queryset=SecondModel.objects.all(),
                      widget=autocomplete.ModelSelect2Multiple(url='url2', forward=(Field('field_field', 'field'),)))

注意使用逗号来区分对象和元组。