This continues the discussion from
https://code.djangoproject.com/ticket/30309. That issue was a misreporting
of the core issue which became apparent after further investigation;
apologies for the noise, I am new to Django.
When a Django model is created with a OneToOneField, or created with a
ForeignKey with:
on_delete=models.DO_NOTHING, db_constraint=False
If the related model does not exist in the database (eg the remote object
was removed or does not currently exist), attempting to access a
relationship on an object will raise a DoesNotExist exception rather than a
RelatedObjectDoesNotExist exception which is raised if the local field is
empty. An example traceback looks like this (full traceback at the end
of this comment <https://code.djangoproject.com/ticket/30309#comment:3>):
[...]
File "django/db/models/fields/related_descriptors.py", line 177, in __get__
rel_obj = self.get_object(instance)
File "django/db/models/fields/related_descriptors.py", line 297, in get_object
return super().get_object(instance)
File "django/db/models/fields/related_descriptors.py", line 144, in get_object
return qs.get(self.field.get_reverse_related_filter(instance))
File "django/db/models/query.py", line 399, in get
self.model._meta.object_name
app.models.person.DoesNotExist: Person matching query does not exist.
By comparison, if the local field's value is empty (eg None/NULL, no
relationship set), then a RelatedObjectDoesNotExist exception will be raised
instead when attempting to access the relationship. This has the effect of
impacting the use of hasattr() if following the one-to-one relationships
<https://docs.djangoproject.com/en/2.1/topics/db/examples/one_to_one/> example
for avoiding exception handling. In this case, DoesNotExist doesn't inherit
from AttributeError, so it isn't swallowed with hasattr()
but RelatedObjectDoesNotExist does so it gets swallowed.
In short, it would be more consistent if accessing a non-existent related
object raised RelatedObjectDoesNotExist. From Simon Charette's comment
<https://code.djangoproject.com/ticket/30309#comment:6> on the original
issue:
I'd be in favor of making ForwardManyToOneDescriptor.get_object raise
> self.RelatedObjectDoesNotExist as the current code clearly doesn't take
> db_constraint=False into account based on the heuristic comment there
> <https://github.com/django/django/blob/755673e1bca7edb6bee7a958f40d9ae54d85d44c/django/db/models/fields/related_descriptors.py#L144>
> .
>
For context, parts of my database are managed outside of Django and retain
records of remote object references as the data may return at some point
(eg a limited view of HR database where staff may or may not have a record
at a given point in time). The local side of the relationship continues to
have a value in case the remote object reappears (eg staff member is now
employed) so in my context, both a value of NULL or a non-existent foreign
key are conceptually the same, meaning there's no person object present.
Regards,
David
--
You received this message because you are subscribed to the Google Groups
"Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/b377a328-8b91-4cb7-af83-1e96d78ebba7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.