So I am trying to update my model by running the following:
FooBar.objects.filter(something=True).update(foobar=F('foo__bar'))
but I get the following error:
FieldError: Joined field references are not permitted in this query
if this is not allowed with F
expressions...how can I achieve this update?
given the information in this ticket, I now understand that this is impossible and will never be implemented in django, but is there any way to achieve this update? maybe with some work around? I do not want to use a loop because there are over 10 million FooBar
objects, so SQL is much faster than python.
In the Django QuerySet API, F() expressions are used to refer to model field values directly in the database.
F() expressions. An F() object represents the value of a model field, transformed value of a model field, or annotated column. It makes it possible to refer to model field values and perform database operations using them without actually having to pull them out of the database into Python memory.
OuterRef: It acts like an F expression except that the check to see if it refers to a valid field isn't made until the outer queryset is resolved. I am experiencing an issue with this using the following example: class ExampleModel(models.Model): date = models.DateField()
Django offers a QuerySet method called select_related() that allows you to retrieve related objects for one-to-many relationships. This translates to a single, more complex QuerySet, but you avoid additional queries when accessing the related objects. The select_related method is for ForeignKey and OneToOne fields.
Django 1.11 adds supports for subqueries. You should be able to do:
from django.db.models import Subquery, OuterRef FooBar.objects.filter(something=True).update( foobar=Subquery(FooBar.objects.filter(pk=OuterRef('pk')).values('foo__bar')[:1]) )
Why don't use raw sql here: Based on this, it will be something like
from django.db import connection raw_query = ''' update app_foobar set app_foobar.foobar = (select app_foo.bar from app_foo where app_foo.id = app_foobar.foo_id) where app_foobar.something = 1; ''' cursor = connection.cursor() cursor.execute(raw_query)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With