Django самый эффективный способ сделать это? - PullRequest
1 голос
/ 18 мая 2010

Я разработал несколько приложений Django, и все они довольно просты с точки зрения того, как я взаимодействую с моделями.

Сейчас я создаю такой, который имеет несколько разных представлений, которые, из-за отсутствия лучшего термина, являются "консервированными" страницами результатов поиска. Все эти страницы возвращают результаты одной и той же модели, но они фильтруются по разным столбцам. На одной странице мы можем фильтровать по типу, на другой мы можем фильтровать по типу и размеру, а на другой мы можем фильтровать только по размеру и т. Д ...

Я написал функцию в views.py, которая используется на каждой из этих страниц, она требует kwargs, и в этом и заключается критерий поиска. Минимум - один фильтр, но в одном из представлений может быть до 4.

Я просто проверяю, содержит ли dict kwargs один из типов фильтров, и поэтому я фильтрую результат по этому значению (я только что написал этот код сейчас, я прошу прощения, если возникнут ошибки, но вы должны понять это):

def get_search_object(**kwargs):

  q = Entry.objects.all()

  if kwargs.__contains__('the_key1'):
    q = q.filter(column1=kwargs['the_key1']) 

  if kwargs.__contains__('the_key2'):
    q = q.filter(column2=kwargs['the_key2']) 

  return q.distinct()

Теперь, в соответствии с django docs (http://docs.djangoproject.com/en/dev/topics/db/queries/#id3),, это нормально, в том случае, если к БД не будет обращен, пока набор не будет оценен, в последнее время я слышал, что это не самый эффективный способ сделать это и, вероятно, следует вместо этого использовать объекты Q.

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

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 18 мая 2010

С точки зрения ресурсов, у вас все хорошо, но есть много способов, которые можно стилистически улучшить, чтобы избежать использования методов двойного подчеркивания и сделать его более гибким и простым в обслуживании.

Если используемые kwargs являются фактическими именами столбцов, то вы сможете довольно легко упростить его, поскольку вы, как бы, делаете это, деконструируя kwargs и восстанавливая его вручную, но только для определенных ключевых слов.

def get_search_object(**kwargs):
    entries = Entry.objects.filter(**kwargs)
    return entries.distinct()

Основное различие заключается в том, что ключи не являются фактическими столбцами и довольно сильно требуют некоторой обработки исключений. Если вы хотите ограничить его определенным набором полей, вы можете указать этот список, а затем сформировать подсказку с действительными записями.

def get_search_object(**kwargs):
    valid_fields = ['the_key1', 'the_key2']
    filter_dict = {}
    for key in kwargs:
        if key in valid_fields:
            filter_dict[key] = kwargs[key]
    entries = Entry.objects.filter(**filter_dict)
    return entries.distinct()

Если вам нужно более интересное решение, которое просто проверяет, является ли допустимым поле в этой модели, вы можете (ab) использовать _meta:

def get_search_object(**kwargs):
    valid_fields = [field.name for field in Entry._meta.fields]
    filter_dict = {}
    for key in kwargs:
        if key in valid_fields:
            filter_dict[key] = kwargs[key]
    entries = Entry.objects.filter(**filter_dict)
    return entries.distinct()
2 голосов
/ 18 мая 2010

В этом случае ваше использование в порядке с точки зрения эффективности. Вам нужно будет использовать объекты Q только в том случае, если вам нужно ИЛИ свои фильтры вместо AND.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...