Cannot update a query once a slice has been taken

django update
how to limit django query
django limit 20
limit in queryset
orm query limit
django get last 3 records
django create or update
django get first 100 records

I am trying to do this:

UserLog.objects.filter(user=user).filter(action='message').filter(timestamp__lt=now)[0:5].update(read=True)

but I am getting this error:

Cannot update a query once a slice has been taken.

(using django 1.2.1)

What am I doing wrong?

As the error states, you cannot call update() on a QuerySet if you took out a slice.

The reason:

  1. Taking a slice is equivalent to a LIMIT statement in SQL.
  2. Issuing an update turns your query into an UPDATE statement.

What you are trying to do would be equivalent to

UPDATE ... WHERE ... LIMIT 5

which is not possible, at least not with standard SQL.

Django: Cannot update a query once a slice has been taken , Solution. As the error states, you cannot call update() on a QuerySet if you took out a slice. The reason: Taking a slice is equivalent to a LIMIT statement in SQL. Cannot update a query once a slice has been taken. (using django 1.2.1) What am I doing wrong? django django-queryset. share | follow | edited Jan 22 at 0:07.

The documentation suggests that something like the following might be possible - I'm not sure if doing the limiting in an inner QuerySet bypasses the check around calling update() after slicing:

inner_q = UserLog.objects.filter(user=user,
                                 action='message',
                                 timestamp__lt=now).values('pk')[0:5]
UserLog.objects.filter(pk__in=inner_q).update(read=True)

Failing that, you could use the in field lookup like so:

ids = UserLog.objects.filter(user=user,
                             action='message',
                             timestamp__lt=now).values_list('pk', flat=True)[0:5]
UserLog.objects.filter(pk__in=list(ids)).update(read=True)

QuerySet first() method gives Cannot filter a query once a slice has , virtualenvs/app/lib/python2.7/site-packages/safedelete/queryset.py", line 98, in _filter_visibility "Cannot filter a query once a slice has been taken. Cannot reorder a query once a slice has been taken. This happens because the adminlist_recursetree attempts to sort the tree on lft value. To really fix this issue, the next page should start with the first root too.

I was getting the same error when attempting to limit the number of records returned by a queryset.

I found that if we're using one of Django's class-based generic views such as the ArchiveIndexView, we can use the paginate_by = attribute to limit the number of records.

For example (in views.py):

from django.views.generic import ArchiveIndexView
from .models import Entry

class HomeListView(ArchiveIndexView):
    """ Blog Homepage """
    model = Entry
    date_field = 'pub_date' 
    template_name = 'appname/home.html'
    queryset = Entry.objects.filter(
        is_active=True).order_by('-pub_date', 'title')
    paginate_by = 30

Django: Cannot update a query once a slice has been taken, Cannot update a query once a slice has been taken. (using django 1.2.1). What am I doing wrong? Solution. As the error states, you cannot call update() on a� There are two aspects to this: recursetree should not reorder querysets (see also #281); Not sure why a slice has been taken. Are you using pagination? If yes, what would you expect the second to last page of comments to look like?

You can't do that. From the Django documents: QuerySet API reference - update

.update a certain number of rows at once : django, The .update examples all use .filter(x=y) but none show how to limit how many to /4285420/django-cannot-update-a-query-once-a-slice-has-been-taken. AssertionError: Cannot filter a query once a slice has been taken. The admin changelist pages that were failing before are fine with the latest PR though This comment has been minimized.

If you want to slice out some of the results of a queryset, you can copy it it to another variable (a shallow copy is enough, which is faster than a deep copy because it just uses references to the original objects.)

import copy

queryset = Mytable.objects.all()
pieceOfQuery = copy.copy(queryset)
pieceOfQuery = pieceOfQuery[:10]

This will keep Django from complaining if you have an order_by filter on your table, since that happens after the slicing if you do it on the main queryset object

Watch out for new possible sources of errors in Django 2.0, TypeError: Cannot reverse a query once a slice has been taken. Updating your codebase to use Django 2.0 will hopefully be smoother now� An update query cannot be used to update data in the following types of fields: Calculated fields The values in calculated fields do not permanently reside in tables. They only exist in your computer's temporary memory after Access calculates them. Because calculated fields do not have a permanent storage location, you cannot update them.

django.db.models.query | Django documentation, stacklevel=2) self.__dict__.update(state) def __repr__(self): data assert self. query.can_filter(), \ "Cannot update a query once a slice has been taken." self. Cancellation should happen quickly but might take a few seconds. The task status API above will continue to list the update by query task until this task checks that it has been cancelled and terminates itself. Change throttling for a requestedit. The value of requests_per_second can be changed on a running update by query using the _rethrottle

query.py, self.query.can_filter(), \ "Cannot update a query once a slice has been taken. _result_cache = None return rows update.alters_data = True def _update(self,� Saying that non-updating updates are so light-weight that it doesn't pay to do the filtering needs to be taken with a grain of salt since the testing has been done, more or less, in a vacuum. But in Production, this table is most likely not isolated.

django.db.models.query — black-goat 0.1 documentation, stacklevel=2) self.__dict__.update(state) def __repr__(self): data assert self. query.can_filter(), \ "Cannot update a query once a slice has been taken." self. All tables can have a relationhip with with Table A using Column 1 . My slicers are derived from table A & Table B . When I select something in Slicer 1 (Table A), it changes the values in Slicer 2 (Table B) which is great. But because Table B has multiple values in column 2 I cannot create a relationship with tables C & D.

Comments
  • Thank you very much. I see my error. Is there any workaround for this? (other than looping over the pks and updating each one?)
  • UPDATE...WHERE...LIMIT 1 is possible in MySQL. Quite useful to avoid "SELECT ... FOR UPDATE" locks.
  • @est you are right, I slightly expanded my answer. Note that OP never mentions the type of database that is used.
  • One probably should place these inside "with transaction.atomic():" block.
  • This is pretty nice and clean, as long as you don't want pagination. I guess you could also grumble that you're making the code unclear, since you're saying it's paginated but then not paginated it in the template, but it's a lot quicker and more easily apparent what's going on than other methods.
  • Thanks for your contribution. Providing only codes as answer will not clearly help OP and readers to mark as correct answer. It will be appreciable if you provide why and how this code resolves the query. What changes you made in the OP's code so that the query is resolved.
  • I know that. but in my case, I do not understand his answer. then, I do that and my problem is solved. and my problem also the same. that's why I'm put here my answer.
  • This is an incorrect (possibly even dangerous) answer. The OP clearly wants to update the first five results. I'm pretty sure your code would update ALL results, THEN it would throw an error because update returns the number of rows, and you can't slice an integer.