Django

Code

Ticket #7095 (closed: fixed)

Opened 2 months ago

Last modified 2 months ago

Error with Many2Many filter() in models managers after queryset-refactor merge

Reported by: fcaprioli@alice.it Assigned to: nobody
Milestone: Component: Database wrapper
Version: SVN Keywords:
Cc: Triage Stage: Accepted
Has patch: 0 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description

Hi, first of all, thank you all for your excellent work; after the qs-rf branch merge, there is a small regression that cause a python error in where.py during an update() if a custom Manager tries to .filter() thru a ManyToManyField? in get_query_set(). This breaks, for example, CurrentSiteManager? with a M2M 'site' field.

So, if you have a model like:

from django.db import models
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager

class Dummy(models.Model):
    dumb = models.TextField()
    site = models.ManyToManyField(Site)
    
    objects = CurrentSiteManager()

def dummy_view(request):
    t = Dummy.objects.create(dumb='abc')
    t.site.add(settings.SITE_ID)
    t.save()

t.save() would give a TypeError?: object of type 'Query' has no len(). At some point, a Query object get passed to make_atom rather than a list. This is the traceback:

Traceback:
File "D:\Arturo\django\core\handlers\base.py" in get_response
  82.                 response = callback(request, *callback_args, **callback_kwargs)
File "D:\Arturo\arturo5\magazine\views_manager_article.py" in article_add
  45.     t.save()
File "D:\Arturo\django\db\models\base.py" in save
  298.         self.save_base()
File "D:\Arturo\django\db\models\base.py" in save_base
  338.                     manager.filter(pk=pk_val)._update(values)
File "D:\Arturo\django\db\models\query.py" in _update
  299.         query.execute_sql(None)
File "D:\Arturo\django\db\models\sql\subqueries.py" in execute_sql
  112.         super(UpdateQuery, self).execute_sql(result_type)
File "D:\Arturo\django\db\models\sql\query.py" in execute_sql
  1432.             sql, params = self.as_sql()
File "D:\Arturo\django\db\models\sql\subqueries.py" in as_sql
  136.         where, params = self.where.as_sql()
File "D:\Arturo\django\db\models\sql\where.py" in as_sql
  61.                     sql, params = self.make_atom(child, qn)
File "D:\Arturo\django\db\models\sql\where.py" in make_atom
  130.             return ('%s IN (%s)' % (field_sql, ', '.join(['%s'] * len(value))),

Exception Type: TypeError at /arturo/magazine/add/
Exception Value: object of type 'Query' has no len()

Attachments

Change History

04/28/08 02:07:17 changed by mtredinnick

(In [7494]) Allow Query objects to be values in query filters. This already existed for relations, but not for normal fields. The latter comes up naturally in some update statements.

Refs #7095

04/28/08 02:08:23 changed by mtredinnick

  • needs_better_patch changed.
  • stage changed from Unreviewed to Accepted.
  • needs_tests changed.
  • needs_docs changed.

The above commit fixes the problem for SQLite and PostgreSQL. Unfortunately, it reveals another bug that affects MySQL users because of MySQL's non-standard UPDATE syntax rules. Working on that piece of the puzzle now.

04/28/08 06:51:16 changed by mtredinnick

(In [7495]) Added a test to demonstrate the remaining problem in #7095.

Only fails for MySQL (because they've made some interesting syntax choices). Refs #7095.

04/28/08 06:51:52 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

(In [7496]) Made some types of nested update queries very slightly more efficient at the database level. Also worked around the fact that MySQL (and maybe other backends we don't know about) cannot select from the table they're updating.

Fixed #7095.


Add/Change #7095 (Error with Many2Many filter() in models managers after queryset-refactor merge)




Change Properties
Action