#21738: models.F does not accept fields generated via QuerySet.extra
----------------------------------------------+--------------------
     Reporter:  tonnzor                       |      Owner:  nobody
         Type:  Uncategorized                 |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  master
     Severity:  Normal                        |   Keywords:
 Triage Stage:  Unreviewed                    |  Has patch:  0
Easy pickings:  0                             |      UI/UX:  0
----------------------------------------------+--------------------
 I found that models.F has a limited usage -- it cannot be used for fields
 added manually via QuerySet.extra(select={...})

 Sample use case:

 {{{
 User.objects.extra(select={'new_is_active': '(CASE WHEN id > 100 THEN 1
 ELSE 0 END)'}).update(is_active=models.F('new_is_active'))
 }}}

 Probably it was intended but if F supports extra fields -- it would be
 really powerful tool. Otherwise you have to fall to raw SQL.

 Also I see at least one way to convert it to SQL -- so there should be a
 way to implement it:

 {{{
 UPDATE auth_user
 set is_active = (CASE WHEN id > 100 THEN 1 ELSE 0 END)
 }}}

 Here is the example:
 {{{

 git clone https://github.com/django/django.git
 cd django
 cp django/bin/django-admin.py .
 ./django-admin.py startproject ttest
 cd ttest
 ln -s ../django
 ./manage.py syncdb --noinput

 echo "from django.contrib.auth.models import *;
 User.objects.extra(select={'new_is_active': '(CASE WHEN id > 100 THEN 1
 ELSE 0 END)'}).update(is_active=models.F('new_is_active'))" | ./manage.py
 shell

 Python 2.7.5 (default, Aug 25 2013, 00:04:04)
 [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
 Type "help", "copyright", "credits" or "license" for more information.
 (InteractiveConsole)
 Traceback (most recent call last):
   File "<console>", line 1, in <module>
   File "/Users/tonnzor/build/django/ttest/django/db/models/query.py", line
 577, in update
     rows = query.get_compiler(self.db).execute_sql(None)
   File
 "/Users/tonnzor/build/django/ttest/django/db/models/sql/compiler.py", line
 958, in execute_sql
     cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
   File
 "/Users/tonnzor/build/django/ttest/django/db/models/sql/compiler.py", line
 752, in execute_sql
     sql, params = self.as_sql()
   File
 "/Users/tonnzor/build/django/ttest/django/db/models/sql/compiler.py", line
 932, in as_sql
     val = SQLEvaluator(val, self.query, allow_joins=False)
   File
 "/Users/tonnzor/build/django/ttest/django/db/models/sql/expressions.py",
 line 14, in __init__
     self.expression.prepare(self, query, allow_joins)
   File
 "/Users/tonnzor/build/django/ttest/django/db/models/expressions.py", line
 149, in prepare
     return evaluator.prepare_leaf(self, query, allow_joins)
   File
 "/Users/tonnzor/build/django/ttest/django/db/models/sql/expressions.py",
 line 62, in prepare_leaf
     query.get_initial_alias(), self.reuse)
   File "/Users/tonnzor/build/django/ttest/django/db/models/sql/query.py",
 line 1375, in setup_joins
     names, opts, allow_many)
   File "/Users/tonnzor/build/django/ttest/django/db/models/sql/query.py",
 line 1302, in names_to_path
     "Choices are: %s" % (name, ", ".join(available)))
 FieldError: Cannot resolve keyword 'new_is_active' into field. Choices
 are: date_joined, email, first_name, groups, id, is_active, is_staff,
 is_superuser, last_login, last_name, logentry, password, user_permissions,
 username
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/21738>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.0fe531f53f89a59edb360ca024293061%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to