Opened 17 years ago

Closed 17 years ago

#3765 closed (invalid)

Exception when adding a new record in the admin form with related recordss

Reported by: ross@… Owned by: Adrian Holovaty
Component: contrib.admin Version: dev
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

With this model:

from django.db import models

class Paper(models.Model):
    class Admin:
        pass

    title = models.CharField(maxlength=200)
    
    def __str__(paper):
        return paper.title
    
class Note(models.Model):
    paper = models.ForeignKey(Paper, edit_inline=models.STACKED, num_in_admin=1)
    text = models.TextField("Comments", core=True)

If I go the the admin site, add a new Paper, enter a title and leave the Note Comments field blank, when I press Save I get this exception:

Traceback (most recent call last):
File "/home/ross/bin/BUILD/lib/python2.5/site-packages/django/core/handlers/base.py" in get_response
  77. response = callback(request, *callback_args, **callback_kwargs)
File "/home/ross/bin/BUILD/lib/python2.5/site-packages/django/contrib/admin/views/decorators.py" in _checklogin
  55. return view_func(request, *args, **kwargs)
File "/home/ross/bin/BUILD/lib/python2.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  39. response = view_func(request, *args, **kwargs)
File "/home/ross/bin/BUILD/lib/python2.5/site-packages/django/contrib/admin/views/main.py" in add_stage
  254. new_object = manipulator.save(new_data)
File "/home/ross/bin/BUILD/lib/python2.5/site-packages/django/db/models/manipulators.py" in save
  172. if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''):
File "/home/ross/bin/BUILD/lib/python2.5/site-packages/django/db/models/fields/__init__.py" in get_manipulator_new_data
  289. return new_data.get(self.name, [self.get_default()])[0]

  IndexError at /admin/papers/paper/add/
  string index out of range

The problem is that new_data.get() returns "", and then doing [0] throws the IndexError.

I can replicate this with Django 0.95.1 and svn (rev 4752). I'm using sqlite3 as a database, Python 2.5 on Ubuntu Feisty Fawn.

Attachments (3)

patch.diff (750 bytes ) - added by dswistowski@… 17 years ago.
patch-revised.diff (747 bytes ) - added by e.j.postma+django-trac@… 17 years ago.
patch.2.diff (1.7 KB ) - added by dswistowski@… 17 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 by Ramiro Morales , 17 years ago

I can't reproduce this on a Debian sarge system with:

$ dpkg -l python2.3 libsqlite3-0 python2.3-pysqlite2
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name                          Version                       Description
+++-=============================-=============================-==========================================================================
ii  python2.3                     2.3.5-3sarge2                 An interactive high-level object-oriented language (version 2.3)
ii  libsqlite3-0                  3.3.5-0.1bpo1                 SQLite 3 shared library
ii  python2.3-pysqlite2           2.3.2-0bpo1                   python interface to SQLite 3

Django is r4752 too.

comment:2 by ross@…, 17 years ago

I know someone else who can't replicate this (I even mailed my entire project), they are using Python 2.4. Maybe this is a 2.5 breakage?

comment:3 by Michael Radziej <mir@…>, 17 years ago

Component: django-admin.pyAdmin interface

component 'django-admin' is for 'management.py' ;-)

comment:4 by dswistowski@…, 17 years ago

Has patch: set
Needs tests: set
Patch needs improvement: set

I can replicate this.
It's python 2.5 issue, with #!/usr/bin/env python2.4 in manage.py all is correct.

I make some changes in code to repair it, but i don't find why new_data.get didn't return list.

by dswistowski@…, 17 years ago

Attachment: patch.diff added

comment:5 by e.j.postma+django-trac@…, 17 years ago

Same here: bug occurs in python2.5 and not in python2.4. Note that this is a duplicate of #3684, but I'm not sure how to merge the two tickets.

A small stylistic note on the patch: I think new_data_getted = new_data.get(self.name, [self.get_default()]) could be changed into new_data_getted = new_data.get(self.name, self.get_default()) since the fact that the default is not a list is already taken care of. Of course I might be missing something here. Ah, and there's a superfluous pair of parentheses around isinstance. I'll be so bold as to attach a revised version of dswistowski's patch. The one serious potential issue that I could think of, for which I don't know enough of django, would be if the intended return value is ever a list.

by e.j.postma+django-trac@…, 17 years ago

Attachment: patch-revised.diff added

comment:6 by dswistowski@…, 17 years ago

I found why new_data.get(self.name, self.get_default()) didn't return list. Issue is in MultiValueDict: in python 2.5:

d = MultiValueDict(a=[1,2,3])
dict(d)

{'a': 3}
But in python 2.4 result is:

d = MultiValueDict(a=[1,2,3])
dict(d)

{'a': [1,2,3]}
With debbuger i found that in python 2.5 dict(d) executes method d.getitem to gather value of da, in python 2.4 that method isn't executed.
I think thad decorate dict.init is the best solution, but i don't know how to decorate methods of builtin types.
In my solution that works i add method todict to MultiValueDict.

by dswistowski@…, 17 years ago

Attachment: patch.2.diff added

comment:7 by e.j.postma+django-trac@…, 17 years ago

Hi,

Your patch looks good to me, but I can't seriously test it at work since Debian has only very spotty 2.5 support (basically just python itself, no modules). Will test at some point at home. I don't see how the snippet of code in your comment could work, however; MultiValueDict does not accept keyword arguments, does it? Not even in trunk.

comment:8 by dswistowski@…, 17 years ago

My fault, the correct is:
For python 2.4:

>>> d = MultiValueDict({'a': [1,2,3]})
>>> dict(d)
{'a': [1,2,3]}

and for python 2.5:

>>> d = MultiValueDict({'a': [1,2,3]})
>>> dict(d)
{'a': 3}

comment:9 by Malcolm Tredinnick, 17 years ago

We apparently don't understand the whole story here, yet. On my Linux system:

>>> sys.version_info
(2, 5, 0, 'final', 0)
>>> d = MultiValueDict({'a': [1,2,3]})
>>> dict(d)
{'a': [1, 2, 3]}

So, I'm not seeing what is claimed to be the root cause of the problem. So what is special about the systems that reporting the problems? What is your OS, for example?

I'm not happy applying any variation of this patch until we understand this a bit better.

comment:10 by dswistowski@…, 17 years ago

This was python bug, my version of python was: 2.5.1c1. After update to 2.5.1final result of dict(d) is correnct.

in reply to:  10 comment:11 by Malcolm Tredinnick, 17 years ago

Resolution: invalid
Status: newclosed

Replying to dswistowski@gmail.com:

This was python bug, my version of python was: 2.5.1c1. After update to 2.5.1final result of dict(d) is correnct.

Good to hear. I've just finished building 2.5.1-final and I can't replicate it either. Going to close this now in light of that information. If somebody can repeat the problem with a non-beta release, please reopen with relevant details.

Note: See TracTickets for help on using tickets.
Back to Top