You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
1.9 KiB

  1. from django.db.models import Count, Q
  2. from django_filters.rest_framework import BooleanFilter, FilterSet
  3. from .models import Example
  4. class DocumentFilter(FilterSet):
  5. spans__isnull = BooleanFilter(field_name='spans', method='filter_annotations')
  6. categories__isnull = BooleanFilter(field_name='categories', method='filter_annotations')
  7. texts__isnull = BooleanFilter(field_name='texts', method='filter_annotations')
  8. def filter_annotations(self, queryset, field_name, value):
  9. queryset = queryset.annotate(num_annotations=Count(
  10. expression=field_name,
  11. filter=Q(**{f"{field_name}__user": self.request.user}) | Q(project__collaborative_annotation=True)
  12. )
  13. )
  14. should_have_annotations = not value
  15. if should_have_annotations:
  16. queryset = queryset.filter(num_annotations__gte=1)
  17. else:
  18. queryset = queryset.filter(num_annotations__lte=0)
  19. return queryset
  20. class Meta:
  21. model = Example
  22. fields = (
  23. 'project', 'text', 'created_at', 'updated_at',
  24. 'categories__label__id', 'spans__label__id',
  25. 'categories__isnull', 'spans__isnull', 'texts__isnull'
  26. )
  27. class ExampleFilter(FilterSet):
  28. confirmed = BooleanFilter(field_name='states', method='filter_by_state')
  29. def filter_by_state(self, queryset, field_name, is_confirmed: bool):
  30. queryset = queryset.annotate(
  31. num_confirm=Count(
  32. expression=field_name,
  33. filter=Q(**{f'{field_name}__confirmed_by': self.request.user}) |
  34. Q(project__collaborative_annotation=True)
  35. )
  36. )
  37. if is_confirmed:
  38. queryset = queryset.filter(num_confirm__gte=1)
  39. else:
  40. queryset = queryset.filter(num_confirm__lte=0)
  41. return queryset
  42. class Meta:
  43. model = Example
  44. fields = ('project', 'text', 'created_at', 'updated_at')