Opened 5 years ago

Closed 5 years ago

#30436 closed Cleanup/optimization (fixed)

on_delete attribute must be callable.

Reported by: Rémy Hubscher Owned by: robinh00d
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

If you set on_delete=None as a ForeignKey field parameter you might get the following error:

  File "django/contrib/admin/options.py", line 1823, in get_deleted_objects
    return get_deleted_objects(objs, request, self.admin_site)
  File "django/contrib/admin/utils.py", line 134, in get_deleted_objects
    collector.collect(objs)
  File "django/contrib/admin/utils.py", line 197, in collect
    return super().collect(objs, source_attr=source_attr, **kwargs)
  File "django/db/models/deletion.py", line 221, in collect
    field.remote_field.on_delete(self, field, sub_objs, self.using)

TypeError: 'NoneType' object is not callable

I believe that we could validate the on_delete value to prevent such behaviour. Or at least tell that None is not a valid on_delete value.

Refs https://docs.djangoproject.com/fr/2.2/ref/models/fields/#django.db.models.ForeignKey.on_delete

Change History (7)

comment:1 by zeynel, 5 years ago

IMO it would be unnecessary to add an extra check for None since it covers all options for on_delete explicitly in documentation:

The possible values for on_delete are found in django.db.models:
...

https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.ForeignKey.on_delete

comment:2 by Mariusz Felisiak, 5 years ago

Component: UncategorizedDatabase layer (models, ORM)
Summary: ForeignKey on_delete parameter should be validatedon_delete attribute must be callable.
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization
Version: 2.2master

Thanks for the report. I can imagine that someone may provide custom on_delete behavior, hence I don't think we should validate this attribute with a static list of on_delete behaviors defined by Django. IMO we can raise

raise ValueError('on_delete must be callable.')

in __init__().

comment:3 by robinh00d, 5 years ago

Owner: changed from nobody to robinh00d
Status: newassigned

comment:4 by robinh00d, 5 years ago

I agree with adding a check in __init__() and raising ValueError('on_delete must be callable.') . I'm going to submit a patch soon, do you have any suggestion as to where I should write my tests?

in reply to:  4 comment:5 by Mariusz Felisiak, 5 years ago

tests/delete looks like a good place for tests.

comment:6 by robinh00d, 5 years ago

Has patch: set

I have submitted a PR:
PR

comment:7 by Mariusz Felisiak <felisiak.mariusz@…>, 5 years ago

Resolution: fixed
Status: assignedclosed

In c231a751:

Fixed #30436 -- Added check that on_delete is callable in ForeignKey and OneToOneField.

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