# Path: advanced_filters/views.py
# class GetFieldChoices(CsrfExemptMixin, StaffuserRequiredMixin,
#                       JSONResponseMixin, View):
#     """
#     A JSONResponse view that accepts a model and a field (path to field),
#     resolves and returns the valid choices for that field.
#     Model must use the "app.Model" notation.
# 
#     If this field is not a simple Integer/CharField with predefined choices,
#     all distinct entries in the DB are presented, unless field name is in
#     ADVANCED_FILTERS_DISABLE_FOR_FIELDS and limited to display only results
#     under ADVANCED_FILTERS_MAX_CHOICES.
#     """
#     def get(self, request, model=None, field_name=None):
#         if model is field_name is None:
#             return self.render_json_response(
#                 {'error': "GetFieldChoices view requires 2 arguments"},
#                 status=400)
#         app_label, model_name = model.split('.', 1)
#         try:
#             model_obj = apps.get_model(app_label, model_name)
#             field = get_fields_from_path(model_obj, field_name)[-1]
#             model_obj = field.model  # use new model if followed a ForeignKey
#         except AttributeError as e:
#             logger.debug("Invalid kwargs passed to view: %s", e)
#             return self.render_json_response(
#                 {'error': "No installed app/model: %s" % model}, status=400)
#         except (LookupError, FieldDoesNotExist) as e:
#             logger.debug("Invalid kwargs passed to view: %s", e)
#             return self.render_json_response(
#                 {'error': force_str(e)}, status=400)
# 
#         choices = field.choices
#         # if no choices, populate with distinct values from instances
#         if not choices:
#             choices = []
#             disabled = getattr(settings, 'ADVANCED_FILTERS_DISABLE_FOR_FIELDS',
#                                tuple())
#             max_choices = getattr(settings, 'ADVANCED_FILTERS_MAX_CHOICES', 254)
#             if field.name in disabled:
#                 logger.debug('Skipped lookup of choices for disabled fields')
#             elif isinstance(field, (models.BooleanField, models.DateField,
#                                     models.TimeField)):
#                 logger.debug('No choices calculated for field %s of type %s',
#                              field, type(field))
#             else:
#                 # the order_by() avoids ambiguity with values() and distinct()
#                 choices = model_obj.objects.order_by(field.name).values_list(
#                     field.name, flat=True).distinct()
#                 # additional query is ok to avoid fetching too many values
#                 if choices.count() <= max_choices:
#                     choices = zip(choices, choices)
#                     logger.debug('Choices found for field %s: %s',
#                                  field.name, choices)
#                 else:
#                     choices = []
# 
#         results = [{'id': c[0], 'text': force_str(c[1])} for c in sorted(
#                    choices, key=lambda x: (x[0] is not None, x[0]))]
# 
#         return self.render_json_response({'results': results})


from django.urls import path
from advanced_filters.views import GetFieldChoices


urlpatterns = [
    path('field_choices/<model>/<field_name>/',
        GetFieldChoices.as_view(),
        name='afilters_get_field_choices'),

    # only to allow building dynamically
    path('field_choices/',

# Path: advanced_filters/views.py
# class GetFieldChoices(CsrfExemptMixin, StaffuserRequiredMixin,
#                       JSONResponseMixin, View):
#     """
#     A JSONResponse view that accepts a model and a field (path to field),
#     resolves and returns the valid choices for that field.
#     Model must use the "app.Model" notation.
# 
#     If this field is not a simple Integer/CharField with predefined choices,
#     all distinct entries in the DB are presented, unless field name is in
#     ADVANCED_FILTERS_DISABLE_FOR_FIELDS and limited to display only results
#     under ADVANCED_FILTERS_MAX_CHOICES.
#     """
#     def get(self, request, model=None, field_name=None):
#         if model is field_name is None:
#             return self.render_json_response(
#                 {'error': "GetFieldChoices view requires 2 arguments"},
#                 status=400)
#         app_label, model_name = model.split('.', 1)
#         try:
#             model_obj = apps.get_model(app_label, model_name)
#             field = get_fields_from_path(model_obj, field_name)[-1]
#             model_obj = field.model  # use new model if followed a ForeignKey
#         except AttributeError as e:
#             logger.debug("Invalid kwargs passed to view: %s", e)
#             return self.render_json_response(
#                 {'error': "No installed app/model: %s" % model}, status=400)
#         except (LookupError, FieldDoesNotExist) as e:
#             logger.debug("Invalid kwargs passed to view: %s", e)
#             return self.render_json_response(
#                 {'error': force_str(e)}, status=400)
# 
#         choices = field.choices
#         # if no choices, populate with distinct values from instances
#         if not choices:
#             choices = []
#             disabled = getattr(settings, 'ADVANCED_FILTERS_DISABLE_FOR_FIELDS',
#                                tuple())
#             max_choices = getattr(settings, 'ADVANCED_FILTERS_MAX_CHOICES', 254)
#             if field.name in disabled:
#                 logger.debug('Skipped lookup of choices for disabled fields')
#             elif isinstance(field, (models.BooleanField, models.DateField,
#                                     models.TimeField)):
#                 logger.debug('No choices calculated for field %s of type %s',
#                              field, type(field))
#             else:
#                 # the order_by() avoids ambiguity with values() and distinct()
#                 choices = model_obj.objects.order_by(field.name).values_list(
#                     field.name, flat=True).distinct()
#                 # additional query is ok to avoid fetching too many values
#                 if choices.count() <= max_choices:
#                     choices = zip(choices, choices)
#                     logger.debug('Choices found for field %s: %s',
#                                  field.name, choices)
#                 else:
#                     choices = []
# 
#         results = [{'id': c[0], 'text': force_str(c[1])} for c in sorted(
#                    choices, key=lambda x: (x[0] is not None, x[0]))]
# 
#         return self.render_json_response({'results': results})


# Path: advanced_filters/urls.py
from django.urls import path
from advanced_filters.views import GetFieldChoices



urlpatterns = [
    path('field_choices/<model>/<field_name>/',
        GetFieldChoices.as_view(),
        name='afilters_get_field_choices'),

    # only to allow building dynamically
    path('field_choices/',

        GetFieldChoices.as_view(),