A
A
Animkim2016-06-16 08:45:03
Django
Animkim, 2016-06-16 08:45:03

What is the difference between queryset and list?

ads = Ads.objects.all()
for ad in ads[:10] 
  pass

ads = ads[:10]
for ad in ads:
  pass

The behavior of these two fors is different, slices work in a QuerySet somehow differently, but how? What's the Difference?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Oscar Django, 2016-06-17
@Animkim

Of course, it's different - after all, this is not a list.
Let's see how it works:
https://github.com/django/django/blob/master/djang...

def __getitem__(self, k):
        if not isinstance(k, (slice,) + six.integer_types):
            raise TypeError
        assert ((not isinstance(k, slice) and (k >= 0)) or
                (isinstance(k, slice) and (k.start is None or k.start >= 0) and
                 (k.stop is None or k.stop >= 0))), \
            "Negative indexing is not supported."

        if self._result_cache is not None:
            return self._result_cache[k]

        if isinstance(k, slice):
            qs = self._clone()
            if k.start is not None:
                start = int(k.start)
            else:
                start = None
            if k.stop is not None:
                stop = int(k.stop)
            else:
                stop = None
            qs.query.set_limits(start, stop)
            return list(qs)[::k.step] if k.step else qs

        qs = self._clone()
        qs.query.set_limits(k, k + 1)
        return list(qs)[0]

In my opinion, everything is very clear here:
- you can transfer either a number or a slice
- while the number or the initial and final values ​​​​of the slice must be at least zero
- if a slice is specified, then a copy of the current queryset is made and low_mark and low_mark are set for the query object of the copy /or high_mark, which in the future will turn into OFFSET and LIMIT of the query to the database.
- then two options are possible:
* if the step is not set, the created copy of the queryset is returned
* if the step is set, then we turn the queryset into a list and apply the step to it
In this case, if the step was not set, then no query to the database was not fulfilled.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question