25

I have a queryset(which is filtered actually) as below

posts = [<Post: published>, <Post: needs>, <Post: be>, <Post: issues>, <Post: to>, <Post: tags>]

But i need to filter the above queryset manually with the some field coming from another table/place etc.

so i had filtered something like below

custom_list = []

for rec in posts:
    if 'string_or_field' in rec.tags.all():
        custom_list.extend(rec)

        or

custom_list = [rec for rec in posts if 'string_or_field' in rec.tags.all()]

So as we can observe above we are creating a list by filtering a queryset, but i want the result as a queryset.

So is there any way to convert the list to queryset object ?

2
  • Why exactly do you need an actual queryset? The point of duck-typing is that you should be able to use any list-like construct. Commented Sep 4, 2013 at 8:38
  • yes actually i need a queryset to perform some operations since it is an object, but i got a list as above , so want to convert the resultant list to queryset Commented Sep 4, 2013 at 13:03

5 Answers 5

19

Actually i had found one way by googling, but this may take a lot of time for querying/generating results if there are huge number of records

custom_list = [rec.id for rec in posts if 'string_or_field' in rec.tags.all()]

querset = MyModel.objects.filter(id__in=custom_list)
Sign up to request clarification or add additional context in comments.

1 Comment

this is exactly what he asked, this shoud be accepted answer
18

You can query the Tag object first and filter Post with those ids:

tags = Tag.objects.filter(field_name='string_or_field')
posts = Post.objects.filter(tags__in=tags)

1 Comment

If you need the queryset to be sorted in the same order as the list, see stackoverflow.com/a/61686789/303056
6

The previous answers are correct if each list item already exists in the database, but sometimes this is not the case. In this case you can create a queryset stub based on the list and implement queryset-methods and queryset-properties as needed.

class ListAsQuerySet(list):

    def __init__(self, *args, model, **kwargs):
        self.model = model
        super().__init__(*args, **kwargs)

    def filter(self, *args, **kwargs):
        return self  # filter ignoring, but you can impl custom filter

    def order_by(self, *args, **kwargs):
        return self

qs = ListAsQuerySet(custom_list, model=Post)

3 Comments

This doesn't work. For a start you can't pass model to a class.
Why? This works for me. Give me more information to resolve your problem.
To pass this to a formset add an ordered method to the class.
4

Here's a simple util that you can run to produce a QS from a list:

def list_to_queryset(model, data):
    from django.db.models.base import ModelBase

    if not isinstance(model, ModelBase):
        raise ValueError(
            "%s must be Model" % model
        )
    if not isinstance(data, list):
        raise ValueError(
            "%s must be List Object" % data
        )

    pk_list = [obj.pk for obj in data]
    return model.objects.filter(pk__in=pk_list)

Comments

0
from typing import Type

from django.db.models import Model


def list_to_queryset(model: Type[Model], data: list):

    assert issubclass(model, Model), "%s must be Model" % model
    assert isinstance(data, list), "%s must be List Object" % data

    pk_list = [obj.pk for obj in data]
    return model.objects.filter(pk__in=pk_list)

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
Thank you for contributing to the Stack Overflow community. This may be a correct answer, but it’d be really useful to provide additional explanation of your code so developers can understand your reasoning. This is especially useful for new developers who aren’t as familiar with the syntax or struggling to understand the concepts. Would you kindly edit your answer to include additional details for the benefit of the community?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.