How to convert a Django QuerySet to a list

By the use of slice operator with step parameter which would cause evaluation of the queryset and create a list.

list_of_answers = answers[::1]

or initially you could have done:

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

You could do this:

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)

Read when QuerySets are evaluated and note that it is not good to load the whole result into memory (e.g. via list()).

Reference: itertools.ifilter

Update with regard to the comment:

There are various ways to do this. One (which is probably not the best one in terms of memory and time) is to do exactly the same :

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)

Why not just call list() on the Queryset?

answers_list = list(answers)

This will also evaluate the QuerySet/run the query. You can then remove/add from that list.


It is a little hard to follow what you are really trying to do. Your first statement looks like you may be fetching the same exact QuerySet of Answer objects twice. First via answer_set.answers.all() and then again via .filter(id__in=...). Double check in the shell and see if this will give you the list of answers you are looking for:

answers = answer_set.answers.all()

Once you have that cleaned up so it is a little easier for you (and others working on the code) to read you might want to look into .exclude() and the __in field lookup.

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

new_answers = answers.exclude(question_answer__in=existing_question_answers)

The above lookup might not sync up with your model definitions but it will probably get you close enough to finish the job yourself.

If you still need to get a list of id values then you want to play with .values_list(). In your case you will probably want to add the optional flat=True.

answers.values_list('id', flat=True)

Tags:

Django