# Path: pyston/utils/decorators.py
# def order_by(field_name):
#     """Sets 'field name' (this is used for grid ordering)"""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.order_by = field_name
#         return func
#     return decorator
# 
# def filter_class(filter_class):
#     """Sets 'filter' class (this attribute is used inside grid and rest)."""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.filter = filter_class
#         return func
#     return decorator
# 
# def filter_by(field_name):
#     """Sets 'field name' (this is used for grid filtering)"""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.filter_by = field_name
#         return func
#     return decorator
# 
# def allow_tags(func):
#     """Allows HTML tags to be returned from resource without escaping"""
#     if isinstance(func, property):
#         func = func.fget
#     func.allow_tags = True
#     return func
# 
# def sorter_class(sorter_class):
#     """Sets 'sorter' class (this attribute is used inside grid and rest)."""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.sorter = sorter_class
#         return func
#     return decorator
# 
# Path: pyston/filters/filters.py
# OPERATORS = Enum(
#     ('GT', 'gt'),
#     ('LT', 'lt'),
#     ('EQ', 'eq'),
#     ('NEQ', 'neq'),
#     ('LTE', 'lte'),
#     ('GTE', 'gte'),
#     ('CONTAINS', 'contains'),
#     ('ICONTAINS', 'icontains'),
#     ('RANGE', 'range'),
#     ('EXACT', 'exact'),
#     ('IEXACT', 'iexact'),
#     ('STARTSWITH', 'startswith'),
#     ('ISTARTSWITH', 'istartswith'),
#     ('ENDSWITH', 'endswith'),
#     ('IENDSWITH', 'iendswith'),
#     ('IN', 'in'),
#     ('RANGE', 'range'),
#     ('ALL', 'all'),
#     ('ISNULL', 'isnull'),
# )
# 
# class IntegerFilterMixin:
#     """
#     Helper that contains cleaner for integer input values.
#     """
# 
#     def clean_value(self, value, operator_slug, request):
#         if value is None:
#             return value
#         try:
#             return int(value)
#         except (ValueError, TypeError):
#             raise FilterValueError(ugettext('Value must be integer'))
# 
# Path: pyston/filters/django_filters.py
# CONTAINS = SimpleOperator('contains')
# 
# class StringFieldFilter(OperatorsModelFieldFilter):
# 
#     operators = (
#         (OPERATORS.ICONTAINS, ICONTAINS),
#         (OPERATORS.CONTAINS, CONTAINS),
#         (OPERATORS.EXACT, EXACT),
#         (OPERATORS.IEXACT, IEXACT),
#         (OPERATORS.STARTSWITH, STARTSWITH),
#         (OPERATORS.ISTARTSWITH, ISTARTSWITH),
#         (OPERATORS.ENDSWITH, ENDSWITH),
#         (OPERATORS.IENDSWITH, IENDSWITH),
#         (OPERATORS.EQ, EQ),
#         (OPERATORS.NEQ, NEQ),
#         (OPERATORS.LT, LT),
#         (OPERATORS.GT, GT),
#         (OPERATORS.LTE, LTE),
#         (OPERATORS.GTE, GTE),
#         (OPERATORS.IN, IN),
#     )
# 
# class SimpleMethodEqualFilter(SimpleEqualFilterMixin, MethodFilter):
#     """
#     Combination of simple equal filter and method filter used for custom method filters.
#     """
#     pass
# 
# Path: pyston/order/django_sorters.py
# class ExtraDjangoSorter(DjangoSorter):
#     """
#     Special type of sorter that updates queryset using annotate or extra queryset method.
#     For this purpose must be implement updated_queryset method which returns queryset with new column
#     that is used for ordering.
#     """
# 
#     def _get_order_string(self):
#         return LOOKUP_SEP.join(chain(('extra_order',), self.identifiers))
# 
#     def update_queryset(self, qs):
#         raise NotImplementedError


from django.db import models
from django.db.models import Count
from django.utils.translation import ugettext_lazy as _
from pyston.utils.decorators import order_by, filter_class, filter_by, allow_tags, sorter_class
from pyston.filters.filters import OPERATORS, IntegerFilterMixin
from pyston.filters.django_filters import CONTAINS, StringFieldFilter, SimpleMethodEqualFilter
from pyston.order.django_sorters import ExtraDjangoSorter



class OnlyContainsStringFieldFilter(StringFieldFilter):

    operators = (
        (OPERATORS.CONTAINS, CONTAINS),
    )


class WatchedIssuesCountMethodFilter(IntegerFilterMixin, SimpleMethodEqualFilter):

    def get_filter_term(self, value, operator, request):
        return {
            'pk__in': User.objects.annotate(
                watched_issues_count=Count('watched_issues')
            ).filter(watched_issues_count=value).values('pk')
        }



# Path: pyston/utils/decorators.py
# def order_by(field_name):
#     """Sets 'field name' (this is used for grid ordering)"""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.order_by = field_name
#         return func
#     return decorator
# 
# def filter_class(filter_class):
#     """Sets 'filter' class (this attribute is used inside grid and rest)."""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.filter = filter_class
#         return func
#     return decorator
# 
# def filter_by(field_name):
#     """Sets 'field name' (this is used for grid filtering)"""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.filter_by = field_name
#         return func
#     return decorator
# 
# def allow_tags(func):
#     """Allows HTML tags to be returned from resource without escaping"""
#     if isinstance(func, property):
#         func = func.fget
#     func.allow_tags = True
#     return func
# 
# def sorter_class(sorter_class):
#     """Sets 'sorter' class (this attribute is used inside grid and rest)."""
#     def decorator(func):
#         if isinstance(func, property):
#             func = func.fget
#         func.sorter = sorter_class
#         return func
#     return decorator
# 
# Path: pyston/filters/filters.py
# OPERATORS = Enum(
#     ('GT', 'gt'),
#     ('LT', 'lt'),
#     ('EQ', 'eq'),
#     ('NEQ', 'neq'),
#     ('LTE', 'lte'),
#     ('GTE', 'gte'),
#     ('CONTAINS', 'contains'),
#     ('ICONTAINS', 'icontains'),
#     ('RANGE', 'range'),
#     ('EXACT', 'exact'),
#     ('IEXACT', 'iexact'),
#     ('STARTSWITH', 'startswith'),
#     ('ISTARTSWITH', 'istartswith'),
#     ('ENDSWITH', 'endswith'),
#     ('IENDSWITH', 'iendswith'),
#     ('IN', 'in'),
#     ('RANGE', 'range'),
#     ('ALL', 'all'),
#     ('ISNULL', 'isnull'),
# )
# 
# class IntegerFilterMixin:
#     """
#     Helper that contains cleaner for integer input values.
#     """
# 
#     def clean_value(self, value, operator_slug, request):
#         if value is None:
#             return value
#         try:
#             return int(value)
#         except (ValueError, TypeError):
#             raise FilterValueError(ugettext('Value must be integer'))
# 
# Path: pyston/filters/django_filters.py
# CONTAINS = SimpleOperator('contains')
# 
# class StringFieldFilter(OperatorsModelFieldFilter):
# 
#     operators = (
#         (OPERATORS.ICONTAINS, ICONTAINS),
#         (OPERATORS.CONTAINS, CONTAINS),
#         (OPERATORS.EXACT, EXACT),
#         (OPERATORS.IEXACT, IEXACT),
#         (OPERATORS.STARTSWITH, STARTSWITH),
#         (OPERATORS.ISTARTSWITH, ISTARTSWITH),
#         (OPERATORS.ENDSWITH, ENDSWITH),
#         (OPERATORS.IENDSWITH, IENDSWITH),
#         (OPERATORS.EQ, EQ),
#         (OPERATORS.NEQ, NEQ),
#         (OPERATORS.LT, LT),
#         (OPERATORS.GT, GT),
#         (OPERATORS.LTE, LTE),
#         (OPERATORS.GTE, GTE),
#         (OPERATORS.IN, IN),
#     )
# 
# class SimpleMethodEqualFilter(SimpleEqualFilterMixin, MethodFilter):
#     """
#     Combination of simple equal filter and method filter used for custom method filters.
#     """
#     pass
# 
# Path: pyston/order/django_sorters.py
# class ExtraDjangoSorter(DjangoSorter):
#     """
#     Special type of sorter that updates queryset using annotate or extra queryset method.
#     For this purpose must be implement updated_queryset method which returns queryset with new column
#     that is used for ordering.
#     """
# 
#     def _get_order_string(self):
#         return LOOKUP_SEP.join(chain(('extra_order',), self.identifiers))
# 
#     def update_queryset(self, qs):
#         raise NotImplementedError


# Path: example/dj/apps/app/models.py
from django.db import models
from django.db.models import Count
from django.utils.translation import ugettext_lazy as _
from pyston.utils.decorators import order_by, filter_class, filter_by, allow_tags, sorter_class
from pyston.filters.filters import OPERATORS, IntegerFilterMixin
from pyston.filters.django_filters import CONTAINS, StringFieldFilter, SimpleMethodEqualFilter
from pyston.order.django_sorters import ExtraDjangoSorter




class OnlyContainsStringFieldFilter(StringFieldFilter):

    operators = (
        (OPERATORS.CONTAINS, CONTAINS),
    )


class WatchedIssuesCountMethodFilter(IntegerFilterMixin, SimpleMethodEqualFilter):

    def get_filter_term(self, value, operator, request):
        return {
            'pk__in': User.objects.annotate(
                watched_issues_count=Count('watched_issues')
            ).filter(watched_issues_count=value).values('pk')
        }



class WatchedIssuesCountSorter(ExtraDjangoSorter):