Code

Opened 7 years ago

Closed 7 years ago

#3765 closed (invalid)

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

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

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@… 7 years ago.
patch-revised.diff (747 bytes) - added by e.j.postma+django-trac@… 7 years ago.
patch.2.diff (1.7 KB) - added by dswistowski@… 7 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 Changed 7 years ago by Ramiro Morales

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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 Changed 7 years ago by ross@…

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 Changed 7 years ago by Michael Radziej <mir@…>

  • Component changed from django-admin.py to Admin interface

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

comment:4 Changed 7 years ago by dswistowski@…

  • 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.

Changed 7 years ago by dswistowski@…

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

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.

Changed 7 years ago by e.j.postma+django-trac@…

comment:6 Changed 7 years ago by dswistowski@…

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.

Changed 7 years ago by dswistowski@…

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

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 Changed 7 years ago by dswistowski@…

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 Changed 7 years ago by mtredinnick

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 follow-up: Changed 7 years ago by dswistowski@…

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

comment:11 in reply to: ↑ 10 Changed 7 years ago by mtredinnick

  • Resolution set to invalid
  • Status changed from new to closed

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.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.