Opened 4 years ago

Closed 5 months ago

#17034 closed Bug (duplicate)

'Invalid literal for int' using admin site called with invalid parameters for inherited models

Reported by: ralphje Owned by: nobody
Component: contrib.admin Version: 1.3
Severity: Normal Keywords:
Cc: vlastimil.zima@…, chris.jerdonek@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using the admin site, gibberish can be entered as the lookup parameter, at least with the change_view and the delete_view, which causes an error. The trace that is sent to me is as follows:

ERROR (internal IP): Internal Server Error: /admin/customers/customer/blahblah/ 

Traceback (most recent call last):

 File "/...../django-1.3/django/core/handlers/base.py", line 111, in get_response
   response = callback(request, *callback_args, **callback_kwargs)

 File "/...../django-1.3/django/contrib/admin/options.py", line 307, in wrapper
   return self.admin_site.admin_view(view)(*args, **kwargs)

 File "/...../django-1.3/django/utils/decorators.py", line 93, in _wrapped_view
   response = view_func(request, *args, **kwargs)

 File "/...../django-1.3/django/views/decorators/cache.py", line 79, in _wrapped_view_func
   response = view_func(request, *args, **kwargs)

 File "/...../django-1.3/django/contrib/admin/sites.py", line 197, in inner
   return view(request, *args, **kwargs)

 File "/...../django-1.3/django/utils/decorators.py", line 28, in _wrapper
   return bound_func(*args, **kwargs)

 File "/...../django-1.3/django/utils/decorators.py", line 93, in _wrapped_view
   response = view_func(request, *args, **kwargs)

 File "/...../django-1.3/django/utils/decorators.py", line 24, in bound_func
   return func(self, *args2, **kwargs2)

 File "/...../django-1.3/django/db/transaction.py", line 217, in inner
   res = func(*args, **kwargs)

 File "/...../django-1.3/django/contrib/admin/options.py", line 947, in change_view
   obj = self.get_object(request, unquote(object_id))

 File "/...../django-1.3/django/contrib/admin/options.py", line 451, in get_object
   return queryset.get(pk=object_id)

 File "/...../django-1.3/django/db/models/query.py", line 341, in get
   clone = self.filter(*args, **kwargs)

 File "/...../django-1.3/django/db/models/query.py", line 550, in filter
   return self._filter_or_exclude(False, *args, **kwargs)

 File "/...../django-1.3/django/db/models/query.py", line 568, in _filter_or_exclude
   clone.query.add_q(Q(*args, **kwargs))

 File "/...../django-1.3/django/db/models/sql/query.py", line 1194, in add_q
   can_reuse=used_aliases, force_having=force_having)

 File "/...../django-1.3/django/db/models/sql/query.py", line 1129, in add_filter
   connector)

 File "/...../django-1.3/django/db/models/sql/where.py", line 67, in add
   value = obj.prepare(lookup_type, value)

 File "/...../django-1.3/django/db/models/sql/where.py", line 316, in prepare
   return self.field.get_prep_lookup(lookup_type, value)

 File "/...../django-1.3/django/db/models/fields/related.py", line 136, in get_prep_lookup
   return self._pk_trace(value, 'get_prep_lookup', lookup_type)

 File "/...../django-1.3/django/db/models/fields/related.py", line 209, in _pk_trace
   v = getattr(field, prep_func)(lookup_type, v, **kwargs)

 File "/...../django-1.3/django/db/models/fields/__init__.py", line 292, in get_prep_lookup
   return self.get_prep_value(value)

 File "/...../django-1.3/django/db/models/fields/__init__.py", line 479, in get_prep_value
   return int(value)

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

It seems that this error only occurs when using a inherited object. The Customer object in my project is defined as follows:

class Customer(Contact):
    language = models.CharField(_('language'), max_length=5, choices=languages, default='nl')
    (etc)

    objects = ContactManager()

Other inherited objects seem to have the same issue.

This issue is quite low-priority, as only the admin site is affected and this only results in error mails to be sent when an user fails with its url. It's not a security leak.

Change History (5)

comment:1 Changed 4 years ago by julien

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

I could verify this issue. As far as the admin is concerned, this is happening in the get_object() method: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py?rev=16934#L475

In that method, the object_id is initially prepared by doing:

object_id = model._meta.pk.to_python(object_id)

In the case of a "normal" model (without inheritance), the pk field is an AutoField and therefore the line above raises a ValidationError. Then, get_object() catches the error, ignores it, and moves on peacefully. So eventually a 404 page is returned.

However, in the case of a "complex" model (using inheritance), the pk is a OneToOneField, whose to_python() method simply returns the value ('blahblah') unchanged without raising any exception. That value is then used in queryset.get(pk=object_id), which raises a ValueError, which isn't caught by get_object().

The question is, should a ValidationError be returned by OneToOneField (or any ForeignKey) when a value with unexpected format is provided to to_python(), or should the admin's get_object() silently catch and ignore ValueError?

Last edited 4 years ago by julien (previous) (diff)

comment:2 Changed 3 years ago by vzima

  • Cc vlastimil.zima@… added

I suggest to fix to_python() calls on relation fields. They should validate data by the rules of related field. Otherwise similar bug (ValueError instead of ValidationError) can occur in different places.

comment:3 Changed 2 years ago by aaugustin

  • Triage Stage changed from Design decision needed to Accepted

This should raise a 404, not a 500.

comment:4 Changed 16 months ago by cjerdonek

  • Cc chris.jerdonek@… added

I ran into a similar issue where passing a non-integer string into ForeignKey.validate() when the corresponding type should be an int raised a ValueError instead of a ValidationError, which caused calling code to break unexpectedly. The stack trace passes through this line:

qs = self.rel.to._default_manager.using(using).filter(
        **{self.rel.field_name: value}
     )

Is this issue a different issue?

comment:5 Changed 5 months ago by kmtracey

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

Original description reported again and fixed by #19951. Issue from comment 4 looks like a different problem, but is hard to duplicate/determine if still a problem without more complete details about how to recreate, and full traceback. Closing since the original issue has been fixed; if the line of code mentioned in comment 4 is really an error that needs its own ticket with more complete details of the problem there.

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