2016-10-11 2 views
0

Я пытаюсь добавить некоторые функциональные возможности, чтобы дать пользователю возможность фильтрации постраничный QuerySet в Django с помощью URL получить параметры, и получил это успешно работает:Есть ли способ проверить, является ли строка допустимым фильтром для набора запросов django?

for f in self.request.GET.getlist('f'): 
    try: 
     k,v = f.split(':', 1) 
     queryset = queryset.filter(**{k:v}) 
    except: 
     pass 

Однако, я надеюсь сделать это таким образом, чтобы не использовать блоки try/except. Есть стандартный способ в django проверить, является ли строка допустимым параметром фильтра?

Например что-то вроде:

my_str = "bad_string_not_in_database" 
if some_queryset.is_valid_filter_string(my_str): 
    some_queryset.filter(**{my_str:100}) 
+0

Если я правильно понял, вы можете найти информацию по ссылке: https://docs.djangoproject.com/en/1.10/topics/db/managers/ –

+0

Я не хочу добавлять дополнительную команду в пользовательскую Менеджер, я хочу знать, существует ли такой способ. –

+0

может быть hasattr на вашей модели, если это фильтр первого уровня. –

ответ

0

Короткий ответ: нет, но есть и другие варианты.

Django не предоставляет и не упрощает создание такой функции проверки, о которой вы просите. Существуют не только поля и форвардные отношения, которые вы можете фильтровать, но и обратные отношения, для которых related_name или related_query_name в поле в совершенно другой модели может быть valid way для фильтрации ваших запросов. Существуют различные механизмы фильтрации, такие как iexact, startswith, regex и т. Д., Которые являются действительными в качестве постфиксных имен этих имен отношений. Итак, чтобы все правильно проверить, вам нужно будет реплицировать много внутреннего кода анализа Django, и это будет большой ошибкой.

Если вы хотите фильтровать поля этой модели и переходы, вы можете использовать hasattr(SomeModel, my_str), но это не всегда будет работать правильно (у вашей модели есть другие атрибуты, кроме полей, таких как методы и свойства).

Вместо того, чтобы делать одеяло except: pass, вы можете по крайней мере уловить конкретную ошибку, которая будет выбрана, если в фильтрационных kwargs (it's TypeError) используется недопустимая строка. Вы также можете вернуть ошибку 400, чтобы сообщить клиенту, что их запрос недействителен, вместо того, чтобы молча продолжать установку без фильтра.

Мое предпочтительное решение заключалось бы в передаче такого типа шаблона, обобщаемой логики в библиотеку, например dynamic-rest.

1

Вы можете начать смотреть на имена полей:

qs.model._meta.get_all_field_names() 

Вы также, вероятно, будет хотеть работать с такими расширениями, как field__icontains, field__gte и т.д. Так будет требоваться больше работы.

Отказ от ответственности: try/except - это лучший способ. Я не знаю, почему вы хотите отклонить этот метод.