Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#25474 closed Bug (worksforme)

RelatedObjectDoesNotExist caused by Model.clean()

Reported by: André Avorio Owned by: nobody
Component: Uncategorized Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hello,

I'm not sure what's going on here.

I have a model:

class Quote(models.Model):
    curation = models.ForeignKey(Curation)
    rental_period = models.PositiveSmallIntegerField('rental period (weeks)', null=True, blank=True, validators=[MinValueValidator(0),MaxValueValidator(260)])
    [...]

    @property
    def type(self):
        return self.curation.opportunity.type

And I decided to implement a validation using:

def clean(self):
        if self.type == 'rental':
            if self.rental_period is None:
                raise ValidationError({'rental_period': 'The rental period must be defined for rental quotes.'})

When I try to create a new Quote object in the admin, I now get a RelatedObjectDoesNotExist error saying Quote has no curation when I don't select any curation from the dropdown menu displayed. When I remove my clean() function and still do not select any curation, I get the normal error message in the admin UI.

Here's the full traceback:

Traceback:
File "/.venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/.venv/lib/python3.4/site-packages/django/contrib/admin/options.py" in wrapper
  616.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/.venv/lib/python3.4/site-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/.venv/lib/python3.4/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File "/.venv/lib/python3.4/site-packages/django/contrib/admin/sites.py" in inner
  233.             return view(request, *args, **kwargs)
File "/maestro/quotes/admin.py" in add_view
  44.         return super(QuoteAdmin, self).add_view(request, form_url, extra_context)
File "/.venv/lib/python3.4/site-packages/django/contrib/admin/options.py" in add_view
  1516.         return self.changeform_view(request, None, form_url, extra_context)
File "/.venv/lib/python3.4/site-packages/django/utils/decorators.py" in _wrapper
  34.             return bound_func(*args, **kwargs)
File "/.venv/lib/python3.4/site-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/.venv/lib/python3.4/site-packages/django/utils/decorators.py" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/contextlib.py" in inner
  30.                 return func(*args, **kwds)
File "/.venv/lib/python3.4/site-packages/django/contrib/admin/options.py" in changeform_view
  1459.             if form.is_valid():
File "/.venv/lib/python3.4/site-packages/django/forms/forms.py" in is_valid
  184.         return self.is_bound and not self.errors
File "/.venv/lib/python3.4/site-packages/django/forms/forms.py" in errors
  176.             self.full_clean()
File "/.venv/lib/python3.4/site-packages/django/forms/forms.py" in full_clean
  394.         self._post_clean()
File "/.venv/lib/python3.4/site-packages/django/forms/models.py" in _post_clean
  430.             self.instance.full_clean(exclude=exclude, validate_unique=False)
File "/.venv/lib/python3.4/site-packages/django/db/models/base.py" in full_clean
  1156.             self.clean()
File "/maestro/quotes/models.py" in clean
  131.         if self.curation != '':
File "/.venv/lib/python3.4/site-packages/django/db/models/fields/related.py" in __get__
  616.                 "%s has no %s." % (self.field.model.__name__, self.field.name)

Exception Type: RelatedObjectDoesNotExist at /admin/quotes/quote/add/
Exception Value: Quote has no curation.

Any clue on what's going on?

Many thanks.

Change History (4)

comment:1 Changed 2 years ago by Claude Paroz

Might be a duplicate of #25431. Could you test with latest 1.8.x branch, or just apply 158b0a28374054b1c3f94a9602b69f93fc980448 in your django install?

comment:2 Changed 2 years ago by André Avorio

Hi claudep! Thanks for your response.

This is what I did:

pip uninstall django
git clone git://github.com/django/django.git django-trunk
pip install -e django-trunk/

Now I'm running Django version 1.10.dev20150927000409.

It complained that I had two unapplied migrations, so I applied them:

Applying admin.0002_logentry_remove_auto_add... OK
Applying auth.0007_alter_validators_add_error_messages... OK

For the record — previously I was using Django 1.8.4.

And finally, I tried performing the same action again, as described above, but I got the exact same error.

comment:3 Changed 2 years ago by Claude Paroz

Resolution: worksforme
Status: newclosed

Re-reading your report, I *think* I understand the problem. As the curation ForeignKey is not nullable in your model and you didn't provide a value for it in the form, you have to be cautious when accessing this attribute in your clean method. You should be able to check if the ForeignKey is set by testing: if self.curation_id is not None (an alternative would be to catch the ObjectDoesNotExist exception).

You might find more help on Django support channels.

comment:4 in reply to:  3 Changed 2 years ago by André Avorio

Replying to claudep:

Re-reading your report, I *think* I understand the problem. As the curation ForeignKey is not nullable in your model and you didn't provide a value for it in the form, you have to be cautious when accessing this attribute in your clean method. You should be able to check if the ForeignKey is set by testing: if self.curation_id is not None (an alternative would be to catch the ObjectDoesNotExist exception).

You're absolutely right, claudep. Thank you for your help; that solved the problem.

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