Django F表达式加入了字段

Rya*_*axe 26 python sql django

所以我试图通过运行以下代码来更新我的模型:

FooBar.objects.filter(something=True).update(foobar=F('foo__bar'))
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

FieldError: Joined field references are not permitted in this query
Run Code Online (Sandbox Code Playgroud)

如果F表达式不允许这样做...我怎样才能实现此更新?

鉴于这张票中的信息,我现在明白这是不可能的,永远不会在django中实现,但有没有办法实现这个更新?也许有一些解决方法?我不想使用循环,因为有超过1000万个FooBar对象,所以SQL比python快得多.

Geo*_*hev 12

Django 1.11添加了对子查询的支持。您应该能够:

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])
)
Run Code Online (Sandbox Code Playgroud)

  • 这应该设置为接受的答案。很有帮助,谢谢! (3认同)
  • 不,它对我不起作用。我收到此错误:django.db.utils.OperationalError:(1093,“您无法在 FROM 子句中指定用于更新的目标表 'xxx'”) (2认同)

lam*_*ave 6

这是 Georgi Yanchev 对两个模型的回答的实现:

class Foo(models.Model):
    bar = models.ForeignKey(Bar)

Foo.objects \
    .filter(foo_field_1=True) \
    .update(foo_field_2=Subquery(
        Bar.objects \
            .filter(id=OuterRef('bar_id')) \
            .values('bar_field_1')[:1]))
Run Code Online (Sandbox Code Playgroud)

  • `pk=OuterRef('bar')` 而不是 `id=OuterRef('bar_id')` 对我来说效果很好,我更喜欢它,因为它只使用模型的属性 (`bar`) 而不是 Django 的内部属性 (`酒吧 ID`)。 (3认同)

era*_*ran 5

为什么不在这里使用原始的sql:基于,它将是类似的东西

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; 
'''

from django.db import connection
cursor = connection.cursor()
cursor.execute(raw_query)
Run Code Online (Sandbox Code Playgroud)