DRF - Как получить один элемент из QuerySet?

Я хочу получить объекты с pk, которые я отправляю через запрос, но мне нужен только один предмет из queryset.

Я хочу, чтобы BatchLog объекты были такими же, как batch_id, и мой запрос возвращает несколько элементов в этом запросе. Я просто хочу одного из них, и неважно, какой именно.

def get_queryset(self):
    return BatchLog.objects.filter(batch_id=self.kwargs["pk"])

Он возвращает pk, но мне нужно QuerySet<[BatchLog, BatchLog]>

Как я могу достичь этого?

Спасибо.

QuerySet — это всегда набор предметов. Это может быть один элемент, поэтому QuerySet<[BatchLog]>, но не QuerySet, который обертывает один элемент.

Willem Van Onsem 14.12.2020 17:24

разве нет способа получить QuerySet, который обертывает один элемент?

Burak Akyalçın 14.12.2020 17:44

: он может обернуть возможный элемент, но в коллекцию, а не как «внешнюю структуру».

Willem Van Onsem 14.12.2020 18:30

Зачем нужен query_set()? Метод get_object() лучше подходит для одного объекта в DRF ViewSet.

Michael Lindsay 15.12.2020 09:27

@MichaelLindsay да, ты прав! но мне нужно вернуться get_object_or_404 и это дает мне MultipleObjectsReturned ошибку. Я не могу получить там последний объект.

Burak Akyalçın 15.12.2020 10:52

@BurakAkyalçın: вопрос скорее в том, подходит ли «подробный просмотр». Обычно имеет смысл возвращать сведения об элементе только в том случае, если мы можем (легко) сослаться на один объект. Просто возвращая «случайный», это выглядит как «втягивание» чего-то в подробное представление, которое по сути не является подробным представлением.

Willem Van Onsem 15.12.2020 10:55

@WillemVanOnsem Я знаю, что есть некоторые проблемы с отношениями, но я не могу это исправить прямо сейчас, все, что мне нужно, это получить случайный элемент из этого запроса :)

Burak Akyalçın 15.12.2020 10:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
7
1 975
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете просто получить первый.

def get_queryset(self):
    return BatchLog.objects.filter(batch_id=self.kwargs["pk"]).first()

def get_object(self):
    queryset = self.get_queryset()
    return get_object_or_404(queryset)

Это возвращает BatchLog, но мне нужен QuerySet<BatchLog>

Burak Akyalçın 14.12.2020 17:22

Вы можете нарезать набор запросов таким образом, чтобы количество результатов ограничивалось одним, поэтому:

def get_queryset(self):
    return BatchLog.objects.filter(batch_id=self.kwargs['pk'])[:1]

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

Если нет товаров, соответствующих фильтру, то это будет пустой QuerySet.

Если использовать filter_backends, то вышеописанное не сработает, поэтому лучше не делать этого на get_querset, а нарезать результат filter_queryset:

class MyListAPIView(ListAPIView):
    # …

    def filter_queryset(self, *args, **kwargs):
        return super().filter_queryset(*args, **kwargs)[:1]

Я получаю сообщение об ошибке после того, как попробовал это AssertionError: Невозможно отфильтровать запрос после того, как фрагмент был взят.

Burak Akyalçın 14.12.2020 17:40

и это возвращает QuerySet<[BatchLog]>, возможно, это проблема

Burak Akyalçın 14.12.2020 17:42

@BurakAkyalçın: это потому, что DRF будет использовать результат при вызове filter_queryset, который делает Джанго. Можешь поделиться полным обзором?

Willem Van Onsem 14.12.2020 18:29

Другие вопросы по теме