Fix MultipleObjectsReturned in EntityModelManager.for_user when entity has multiple managers - #329
Open
Leggendario12 wants to merge 4 commits into
Open
Fix MultipleObjectsReturned in EntityModelManager.for_user when entity has multiple managers#329Leggendario12 wants to merge 4 commits into
Leggendario12 wants to merge 4 commits into
Conversation
EntityModelManager.for_user builds a query using OR across a ManyToMany (managers) relationship. Without distinct(), entities with 2+ managers produce duplicate rows from the JOIN, causing .get() to raise MultipleObjectsReturned. Add .distinct() to collapse the duplicates.
When no period has been closed, last_closing_date is None. Comparing None < receipt_date raises TypeError. Treat None as before all dates (i.e. deletion is always allowed when no period has been closed).
Files now stored as {slug}_{pk}/logo/logo{ext} instead of the root
of the media bucket, making per-entity folders in R2/S3 cleaner.
Logo is now managed exclusively via the EntityInvoiceSettings extension model in the consuming application, keeping the core entity model lean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
EntityModelManager.for_useruses an OR filter across aManyToManyrelationship (managers). When an entity hasmore than one manager, the underlying SQL
LEFT OUTER JOINproduces one row per manager match, which causes.get()calls downstream to raiseMultipleObjectsReturned— even though only one entity actually matches.Root Cause
Scenario That Triggers the Bug
The entity itself is not duplicated in the database — the duplicate rows are an artefact of the many-to-many join.
The count equals the number of managers on the entity.
The Fix
Add
.distinct()to collapse the duplicate rows produced by the join:Before
return
qs.filter(Q(admin=user_model) | Q(managers__in=[user_model]))After
return
qs.filter(Q(admin=user_model) | Q(managers__in=[user_model])).distinct()This is the standard Django pattern when filtering across ManyToMany relationships — see the Django docs on
spanning multi-valued relationships
(https://docs.djangoproject.com/en/stable/topics/db/queries/#spanning-multi-valued-relationships).
The fix is a one-line change. It has no effect on which entities are returned — distinct() only removes duplicate
rows. A regression test: