what is query.clone(), queryset.clone() for in django?

15,212

Solution 1

There are two main reasons for clone():

  1. It allows chaining. When you chain querysets together (for example, multiple filter() calls), you want a fresh copy of the queryset each time that you can modify.

  2. It allows you to avoid stale cache results. Since querysets cache their results when they are evaluated, if you want to make sure you hit the database again you need to clone the queryset.

If you know what you're doing you could use it, but note that it isn't a public API. In this interesting Django developers thread the developers talk about whether or not clone() should be public. They decide against it, in part because:

The biggest problem with public .clone() method is that the private ._clone() doesn't do just cloning. There are some cases where cloning also changes how the QuerySet behaves.

Solution 2

As Kevin points out in his answer, the clone() method is not a documented part of the Django API. However, the all() method is fully documented, and does what you probably wanted from clone().

all()

Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result. After calling all() on either object, you’ll definitely have a QuerySet to work with.

When a QuerySet is evaluated, it typically caches its results. If the data in the database might have changed since a QuerySet was evaluated, you can get updated results for the same query by calling all() on a previously evaluated QuerySet.

Share:
15,212

Related videos on Youtube

eugene
Author by

eugene

I am working on littlehome.kr If you'd like to give a hand, please join us.

Updated on September 15, 2022

Comments

  • eugene
    eugene over 1 year

    I see clone() being used extensively in django code

    queryset.query.clone()  
    queryset.clone()
    

    What is it for and should I mimic the behavior in my queryset or manager methods?

  • eugene
    eugene about 10 years
    The reason you need clone() for chaining is because?
  • Kevin Christopher Henry
    Kevin Christopher Henry about 10 years
    @eugene: Although it's possible to have a chaining API that operates on a single object, Django's queryset API is specifically designed to return a new queryset each time the query is modified. The most straightforward way to do that is to copy (i.e. clone) the existing queryset, modify it, and then return the new object.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com almost 8 years
    And in 1.9.6, all() calls the internal _clone method: github.com/django/django/blob/1.9.6/django/db/models/… Related question: stackoverflow.com/questions/22804252/…