#11311: Deleting model instance with a string id and m2m relation fails
------------------------------------------+---------------------------------
 Reporter:  ronny                         |       Owner:  nobody    
   Status:  new                           |   Milestone:  1.1       
Component:  Database layer (models, ORM)  |     Version:  SVN       
 Keywords:  delete string pk m2m          |       Stage:  Unreviewed
Has_patch:  0                             |  
------------------------------------------+---------------------------------
 Say a model has a CharField as its primary key and the model also has a
 many to many relation to some other "normal" model, deleting an instance
 of the model with string primary key like "abc" fails with an exception,
 but not with a string id that can be converted into an int, e.g. "1".
 Seems like the code assumes that primary keys are always int()?

 Using django from svn trunk r10982.

 The following is a very small test case (models.py) that demonstrate the
 issue.

 {{{
 from django.db import models

 class Line(models.Model):
     name = models.CharField(max_length=100)

 class Worksheet(models.Model):
     id = models.CharField(primary_key=True, max_length=100)
     lines = models.ManyToManyField(Line, blank=True, null=True)
 }}}

 After running syncdb (happens with sqlite3 and postgresql-8.3 btw), then
 the following is the output from `manage.py shell`:

 {{{
 In [1]: from x.y.models import *

 In [2]: w = Worksheet(id='abc')

 In [3]: w.save()

 In [4]: w
 Out[4]: <Worksheet: Worksheet object>

 In [5]: w.delete()
 ERROR: An unexpected error occurred while tokenizing input
 The following traceback may be corrupted or invalid
 The error message is: ('EOF in multi-line statement', (20, 0))

 ---------------------------------------------------------------------------
 ValueError                                Traceback (most recent call
 last)

 /private/tmp/x/<ipython console> in <module>()

 /Library/Python/2.5/site-packages/django/db/models/base.pyc in
 delete(self)
     567
     568         # Actually delete the objects.
 --> 569         delete_objects(seen_objs)
     570
     571     delete.alters_data = True

 /Library/Python/2.5/site-packages/django/db/models/query.pyc in
 delete_objects(seen_objs)
    1035             pk_list = [pk for pk,instance in items]
    1036             del_query = sql.DeleteQuery(cls, connection)
 -> 1037             del_query.delete_batch_related(pk_list)
    1038
    1039             update_query = sql.UpdateQuery(cls, connection)

 /Library/Python/2.5/site-packages/django/db/models/sql/subqueries.pyc in
 delete_batch_related(self, pk_list)
      68                 where.add((Constraint(None, f.m2m_column_name(),
 f), 'in',
      69                         pk_list[offset : offset +
 GET_ITERATOR_CHUNK_SIZE]),
 ---> 70                         AND)
      71                 if w1:
      72                     where.add(w1, AND)

 /Library/Python/2.5/site-packages/django/db/models/sql/where.pyc in
 add(self, data, connector)
      54         if hasattr(obj, "process"):
      55             try:
 ---> 56                 obj, params = obj.process(lookup_type, value)
      57             except (EmptyShortCircuit, EmptyResultSet):
      58                 # There are situations where we want to short-
 circuit any

 /Library/Python/2.5/site-packages/django/db/models/sql/where.pyc in
 process(self, lookup_type, value)
     267         try:
     268             if self.field:
 --> 269                 params =
 self.field.get_db_prep_lookup(lookup_type, value)
     270                 db_type = self.field.db_type()
     271             else:

 /Library/Python/2.5/site-packages/django/db/models/fields/related.py in
 get_db_prep_lookup(self, lookup_type, value)
     160             return [pk_trace(value)]
     161         if lookup_type in ('range', 'in'):
 --> 162             return [pk_trace(v) for v in value]
     163         elif lookup_type == 'isnull':
     164             return []

 /Library/Python/2.5/site-packages/django/db/models/fields/related.py in
 pk_trace(value)
     137             if lookup_type in ('range', 'in'):
     138                 v = [v]
 --> 139             v = field.get_db_prep_lookup(lookup_type, v)
     140             if isinstance(v, list):
     141                 v = v[0]

 /Library/Python/2.5/site-packages/django/db/models/fields/__init__.pyc in
 get_db_prep_lookup(self, lookup_type, value)
     210             return [self.get_db_prep_value(value)]
     211         elif lookup_type in ('range', 'in'):
 --> 212             return [self.get_db_prep_value(v) for v in value]
     213         elif lookup_type in ('contains', 'icontains'):
     214             return ["%%%s%%" %
 connection.ops.prep_for_like_query(value)]

 /Library/Python/2.5/site-packages/django/db/models/fields/__init__.pyc in
 get_db_prep_value(self, value)
     359         if value is None:
     360             return None
 --> 361         return int(value)
     362
     363     def contribute_to_class(self, cls, name):

 ValueError: invalid literal for int() with base 10: 'abc'

 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/11311>
Django <http://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 post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to