Как преобразовать Django QuerySet в список - PullRequest
96 голосов
/ 13 декабря 2010

У меня есть следующее:

answers = Answer.objects.filter(id__in=[answer.id for answer in answer_set.answers.all()])

потом, позже:

for i in range(len(answers)):
    # iterate through all existing QuestionAnswer objects
    for existing_question_answer in existing_question_answers:
        # if an answer is already associated, remove it from the
        # list of answers to save
        if answers[i].id == existing_question_answer.answer.id:
            answers.remove(answers[i])           # doesn't work
            existing_question_answers.remove(existing_question_answer)

Я получаю сообщение об ошибке:

'QuerySet' object has no attribute 'remove'

Я перепробовал всепреобразовать QuerySet в стандартный набор или список.Ничего не работает.

Как я могу удалить элемент из QuerySet, чтобы он не удалял его из базы данных и не возвращал новый QuerySet (так как он в цикле, который не будет работать)?

Ответы [ 7 ]

253 голосов
/ 13 декабря 2010

Почему бы просто не вызвать list () в наборе запросов?

answers_list = list(answers)

Это также оценит QuerySet / выполнить запрос. Затем вы можете удалить / добавить из этого списка.

35 голосов
/ 13 декабря 2010

Вы можете сделать это:

import itertools

ids = set(existing_answer.answer.id for existing_answer in existing_question_answers)
answers = itertools.ifilter(lambda x: x.id not in ids, answers)

Чтение при оценке QuerySets и обратите внимание, что нецелесообразно загружать весь результат в память (напримерчерез list()).

Ссылка: itertools.ifilter

Обновление в отношении комментария:

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

answer_ids = set(answer.id for answer in answers)
existing_question_answers = filter(lambda x: x.answer.id not in answers_id, existing_question_answers)
31 голосов
/ 13 декабря 2010

Немного трудно следить за тем, что вы действительно пытаетесь сделать.Ваше первое утверждение выглядит так, как будто вы дважды выбираете один и тот же объект QuerySet of Answer.Сначала через answer_set.answers.all(), а затем снова через .filter(id__in=...).Дважды проверьте в оболочке и посмотрите, даст ли это вам список ответов, которые вы ищете:

answers = answer_set.answers.all()

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

existing_question_answers = QuestionAnswer.objects.filter(...)

new_answers = answers.exclude(question_answer__in=existing_question_answers)

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

Если вам все еще нужно получить список идентификаторовзначения, то вы хотите играть с .values_list () .В вашем случае вы, вероятно, захотите добавить дополнительную квартиру = True.

answers.values_list('id', flat=True)
16 голосов
/ 02 декабря 2015

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

list_of_answers = answers[::1]

или изначально вы могли бы сделать:

answers = Answer.objects.filter(id__in=[answer.id for answer in
        answer_set.answers.all()])[::1]
11 голосов
/ 19 апреля 2018

Вы можете напрямую конвертировать, используя ключевое слово list.Например:

obj=emp.objects.all()
list1=list(obj)

Используя приведенный выше код, вы можете напрямую преобразовать результат набора запросов в list.

Здесь list - ключевое слово и obj является результатом набора запросов, а list1 является переменной в той переменной, в которой мы храним преобразованный результат, который в list.

2 голосов
/ 10 ноября 2016

Почему бы просто не позвонить .values('reqColumn1','reqColumn2') или .values_list('reqColumn1','reqColumn2') в наборе запросов?

answers_list = models.objects.values('reqColumn1','reqColumn2')

result = [{'reqColumn1':value1,'reqColumn2':value2}]

OR

answers_list = models.objects.values_list('reqColumn1','reqColumn2')

result = [(value1,value2)]

Вы можете выполнить все операции с этим QuerySet, которые вы выполняете для списка.

0 голосов
/ 31 октября 2018
def querySet_to_list(qs):
    """
    this will return python list<dict>
    """
    return [dict(q) for q in qs]

def get_answer_by_something(request):
    ss = Answer.objects.filter(something).values()
    querySet_to_list(ss) # python list return.(json-able)

этот код конвертирует django queryset в список python

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