Фильтруйте поле «многие ко многим» с помощью Django DataTable - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть представление Django, созданное с помощью django-datatables-view:

class ActivityListJson(BaseDatatableView):
    columns = ['description', 'entities']
    max_display_length = 500

    def get_initial_queryset(self):
        return Activity.objects.all().prefetch_related('entities')

    def prepare_results(self, qs):
        data = []
        for item in qs:
            entities = []
            for entity in item.entities.all():
                entities.append(entity.entityDescription)
            entities = ''.join(entities)
            data.append([item.description,
                         entities])
        return data

С объектом для цикла в prepare_results() я могу показать список объектов в DataTable. Тем не менее, я сталкиваюсь с Related Field got invalid lookup: ошибками с такими трассировками:

Traceback:  

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\core\handlers\exception.py" in inner
  41.             response = get_response(request)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\core\handlers\base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\core\handlers\base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\views\generic\base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\views\generic\base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django_datatables_view\mixins.py" in get
  51.             func_val = self.get_context_data(**kwargs)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django_datatables_view\base_datatable_view.py" in get_context_data
  314.             return self.handle_exception(e)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django_datatables_view\base_datatable_view.py" in handle_exception
  265.         raise e

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django_datatables_view\base_datatable_view.py" in get_context_data
  284.             qs = self.filter_queryset(qs)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django_datatables_view\base_datatable_view.py" in filter_queryset
  254.             qs = qs.filter(q)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\db\models\query.py" in filter
  784.         return self._filter_or_exclude(False, *args, **kwargs)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\db\models\query.py" in _filter_or_exclude
  802.             clone.query.add_q(Q(*args, **kwargs))

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\db\models\sql\query.py" in add_q
  1250.         clause, _ = self._add_q(q_object, self.used_aliases)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\db\models\sql\query.py" in _add_q
  1270.                     current_negated, allow_joins, split_subq)

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\db\models\sql\query.py" in _add_q
  1276.                     allow_joins=allow_joins, split_subq=split_subq,

File "D:\Python\Anaconda3\envs\django\lib\site-packages\django\db\models\sql\query.py" in build_filter
  1201.                 raise FieldError('Related Field got invalid lookup: {}'.format(lookups[0]))

Полагаю, мне нужно переопределить filter_queryset(), но я не уверен, с чего начать. Я понимаю, что filter_queryset() использует columns для фильтрации основного столбца. Это обходит настройку данных в prepare_results(). Вот мои модели:

class Entity(models.Model):
    entity = models.CharField(primary_key=True, max_length=25)
    entityDescription = models.CharField(max_length=400)

    def __str__(self):
        """
        Returns default string representation of Entity.
        """
        return '%s - %s - %s' % (self.entity,
                                 self.entityDescription)

class Activity(models.Model):
    description = models.CharField(max_length=500)
    entities = models.ManyToManyField(Entity, related_name='entities')

Как мне настроить вид, чтобы правильно ссылаться на поле M2M? В идеале я бы также получил строковое представление __str__ из Entity, а не просто поле entityDescription.

...