Фильтр Django против get для одного объекта?

$db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);

Put " DB_HOST " instead of " DB_SERVER " also 
put " DB_USER " Instead of " DB_USERNAME " 

, чем работает нормально!

136
задан daaawx 4 May 2019 в 05:50
поделиться

9 ответов

get () предоставляется специально для этого случая. Используйте его.

Вариант 2 почти точно соответствует тому, как метод get () фактически реализован в Django, поэтому не должно быть разницы в «производительности» (и тот факт, что вы думаете об этом, указывает на вы нарушаете одно из основных правил программирования, а именно пытаетесь оптимизировать код еще до того, как он был написан и профилирован - пока у вас не будет кода и вы не сможете его запустить, вы не знаете, как он будет работать, и пытаетесь оптимизировать до этого - путь боли).

167
ответ дан 23 November 2019 в 23:33
поделиться

Извините, что добавил еще одно взятие по этой проблеме, но я использую django paginator, и в моем приложении администрирования данных, пользователю разрешают выбрать, что запросить на. Иногда это - идентификатор документа, но иначе это - общий запрос, возвращая больше чем один объект, т.е. Queryset.

, Если пользовательские запросы идентификатор, я могу работать:

Record.objects.get(pk=id)

, который бросает ошибку в paginator django, потому что это - Запись и не Queryset Записей.

я должен работать:

Record.objects.filter(pk=id)

, Который возвращает Queryset с одним объектом в нем. Тогда paginator работает просто великолепно.

0
ответ дан 23 November 2019 в 23:33
поделиться

1 правильный. В Python накладные расходы на исключение равны возврату. В качестве упрощенного доказательства вы можете посмотреть this .

2 Это то, что Django делает на бэкэнде. get вызывает фильтр и вызывает исключение, если ни один элемент не найден или если найдено более одного объекта.

16
ответ дан 23 November 2019 в 23:33
поделиться

Я не могу говорить ни о каком опыте работы с Django, но вариант № 1 четко сообщает системе, что вы запрашиваете 1 объект, а второй вариант - нет. Это означает, что вариант №1 мог бы более легко использовать преимущества индексов кеша или базы данных, особенно если атрибут, по которому вы фильтруете, не гарантированно будет уникальным.

Кроме того (опять же, предполагая), второй вариант может потребовать создания некоторых тип коллекции результатов или объект-итератор, поскольку вызов filter () обычно может возвращать много строк. Вы бы обошли это с помощью get ().

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

8
ответ дан 23 November 2019 в 23:33
поделиться

Почему все это работает? Замените 4 строки на 1 встроенный ярлык. (Это делает свою попытку / кроме.)

from django.shortcuts import get_object_or_404

obj = get_object_or_404(MyModel, id=1)
8
ответ дан 23 November 2019 в 23:33
поделиться

Дополнительная информация об исключениях. Если их не собрать, они почти ничего не стоят. Таким образом, если вы знаете, что у вас, вероятно, будет результат, используйте исключение, поскольку, используя условное выражение, вы платите стоимость проверки каждый раз, несмотря ни на что. С другой стороны, они стоят немного больше, чем условное выражение, когда они возникают, поэтому, если вы ожидаете, что результат не будет с некоторой частотой (скажем, в 30% случаев, если память не изменяет), условная проверка оказывается быть немного дешевле.

Но это ORM Django, и, вероятно, обратный путь к базе данных или даже кешированный результат, вероятно, будут доминировать над характеристиками производительности, поэтому в этом случае предпочтение отдается удобочитаемости, поскольку вы ожидаете ровно один результат, используйте get () .

7
ответ дан 23 November 2019 в 23:33
поделиться

Интересный вопрос, но для меня вариант № 2 вызывает неприятный запах преждевременной оптимизации. Я не уверен, что более производительно, но вариант №1 определенно выглядит и кажется мне более питоническим.

1
ответ дан 23 November 2019 в 23:33
поделиться

Вы можете установить модуль под названием django-annoying , а затем сделать следующее:

from annoying.functions import get_object_or_None

obj = get_object_or_None(MyModel, id=1)

if not obj:
    #omg the object was not found do some error stuff
29
ответ дан 23 November 2019 в 23:33
поделиться

Вариант 1 более элегантен, но обязательно используйте try..except.

По собственному опыту могу сказать, что иногда вы уверены, что не может быть более одного соответствующий объект в базе данных, и все же будет два ... (за исключением, конечно, получения объекта по его первичному ключу).

0
ответ дан 23 November 2019 в 23:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: