As I've said on the ticket I think we should make this change as it's backward compatible and more coherent with the other RelatedObjectDoesNotExist usages of the related fields API.
Cheers, Simon Le mardi 16 avril 2019 07:22:52 UTC-4, David Beitey a écrit : > > 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 django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. 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/cdcf9eda-c691-4354-b806-51de36ec6d24%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.