#25298: Forbid QuerySet filtering by a related field that expects a single value when multiple values are returned -------------------------------------+------------------------------------- Reporter: timgraham | Owner: Y3K Type: | Status: assigned Cleanup/optimization | Component: Database layer | Version: 1.8 (models, ORM) | Severity: Normal | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+-------------------------------------
Comment (by Naddiseo): To re-add my opinion on this from the other issue: I think the ORM should be consistent across backends, so it should throw an exception if the inner queryset could return more than a single row. My reasoning is basically to prevent vendor lock-in; Django was (is?) marketed as being mix-and-match for the backends such as database and templating, and Django would take care of the rest. (But, I'm fairly biased on this since I just spent a few unpleasant weeks converting raw mysql in our code to use ORM so that we can eventually switch to postgresql.) For the use-case that akaariai brought up, perhaps it would have to be changed to accept a limit of one: {{{#!python Foo.objects.filter(related_model__exact=RelatedModel.objects.values('pk')[:1]) # SELECT * FROM Foo WHERE related_model_id = (SELECT pk FROM RelatedModel LIMIT 1); }}} This way it's explicit that you only want 0 or 1 returned from the subquery. As a side note, does `__exact` allow passing in a model instance? {{{#!python Foo.objects.filter(related_model__exact=RelatedModel.objects.get(pk=1)) }}} Of course, it's not exactly the same since the `.get` can throw a `DoesNotExist` exception, and it generates two queries. An alternate solution is to implicitly add limits, or change `=` to `IN` if the subquery may return multiple results. However, I am against this behaviour since - although it may be intuitive - it's implicit and may be the result of a programmer error that should really be raised as an error instead of silently accepted. -- Ticket URL: <https://code.djangoproject.com/ticket/25298#comment:8> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/067.dbda77a7fba94aeb5163ddfed7d9d0f1%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.