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.

60 lines
2.1 KiB

2 years ago
2 years ago
  1. from django.db.models import Count, Q, QuerySet
  2. from django_filters.rest_framework import BooleanFilter, CharFilter, FilterSet
  3. from .models import Example
  4. class ExampleFilter(FilterSet):
  5. confirmed = BooleanFilter(field_name="states", method="filter_by_state")
  6. label = CharFilter(method="filter_by_label")
  7. assignee = CharFilter(method="filter_by_assignee")
  8. def filter_by_state(self, queryset, field_name, is_confirmed: bool):
  9. queryset = queryset.annotate(
  10. num_confirm=Count(
  11. expression=field_name,
  12. filter=Q(**{f"{field_name}__confirmed_by": self.request.user})
  13. | Q(project__collaborative_annotation=True),
  14. )
  15. )
  16. if is_confirmed:
  17. queryset = queryset.filter(num_confirm__gte=1)
  18. else:
  19. queryset = queryset.filter(num_confirm__lte=0)
  20. return queryset
  21. def filter_by_label(self, queryset: QuerySet, field_name: str, label: str) -> QuerySet:
  22. """Filter examples by a given label name.
  23. This performs filtering on all of the following labels at once:
  24. - categories
  25. - spans
  26. - relations
  27. - bboxes
  28. - segmentations
  29. Todo: Consider project type to make filtering more efficient.
  30. Args:
  31. queryset (QuerySet): QuerySet to filter.
  32. field_name (str): This equals to `label`.
  33. label (str): The label name to filter.
  34. Returns:
  35. QuerySet: Filtered examples.
  36. """
  37. queryset = queryset.filter(
  38. Q(categories__label__text=label)
  39. | Q(spans__label__text=label)
  40. | Q(relations__type__text=label)
  41. | Q(bboxes__label__text=label)
  42. | Q(segmentations__label__text=label)
  43. )
  44. return queryset
  45. def filter_by_assignee(self, queryset: QuerySet, field_name: str, assignee: str) -> QuerySet:
  46. return queryset.filter(assignments__assignee__username=assignee)
  47. class Meta:
  48. model = Example
  49. fields = ("project", "text", "created_at", "updated_at", "label", "assignee")