-
Notifications
You must be signed in to change notification settings - Fork 5
feat: Performance optimization for versioned changelist #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideOptimizes how story content is retrieved for draft views by leveraging djangocms-versioning’s pre-fetched current contents and removing unnecessary prefetches, thereby reducing redundant database queries for versioned, language-specific content. Sequence diagram for optimized draft content retrieval in get_contentsequenceDiagram
actor View
participant Story as StoryInstance
participant VersioningCache as VersioningPrefetchCache
participant PostContentQS as PostContentQueryset
View->>Story: get_content(language, show_draft_content=True)
alt show_draft_content is True
opt versioning prefetch cache available
Story->>VersioningCache: check attribute _current_contents
alt _current_contents exists
Story-->>View: return _current_contents[0]
else _current_contents missing
Story->>PostContentQS: postcontent_set(manager=admin_manager)
PostContentQS->>PostContentQS: current_content()
PostContentQS->>PostContentQS: filter(language)
PostContentQS-->>Story: first()
Story-->>View: return cached content
end
end
else show_draft_content is False
Story->>PostContentQS: postcontent_set
PostContentQS->>PostContentQS: filter(language)
PostContentQS-->>Story: first()
Story-->>View: return cached content
end
Updated class diagram for Story get_content optimizationclassDiagram
class Story {
_content_cache
_current_contents
get_content(language, show_draft_content)
}
class PostContentQueryset {
current_content()
filter(language)
first()
}
Story "1" --> "*" PostContentQueryset : postcontent_set
class VersioningPrefetchCache {
_current_contents
}
Story --> VersioningPrefetchCache : uses when show_draft_content
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- When using the
_current_contentscache, you’re bypassing both the existing_content_cachemechanism andprefetch_related, which changes behavior compared to the non-versioned path; consider still caching the result under_content_cache[key]and validating that skippingprefetch_relateddoesn’t introduce N+1 queries for placeholders/categories. - Accessing
self._current_contents[0]assumes the prefetch list is non-empty; it would be safer to handle the empty case explicitly (e.g., returningNoneor falling back to the queryset) to avoid an IndexError when no current content exists for the requested language.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- When using the `_current_contents` cache, you’re bypassing both the existing `_content_cache` mechanism and `prefetch_related`, which changes behavior compared to the non-versioned path; consider still caching the result under `_content_cache[key]` and validating that skipping `prefetch_related` doesn’t introduce N+1 queries for placeholders/categories.
- Accessing `self._current_contents[0]` assumes the prefetch list is non-empty; it would be safer to handle the empty case explicitly (e.g., returning `None` or falling back to the queryset) to avoid an IndexError when no current content exists for the requested language.
## Individual Comments
### Comment 1
<location> `djangocms_stories/models.py:371-372` </location>
<code_context>
if show_draft_content:
+ # Check for djangcms-versioning's prefetch cache - it's already language-filtered
+ # If present we avoid unnecessary DB queries
+ if hasattr(self, "_current_contents"):
+ return self._current_contents[0]
qs = self.postcontent_set(manager="admin_manager").current_content()
else:
</code_context>
<issue_to_address>
**issue:** Accessing `_current_contents[0]` can raise on an empty collection and bypasses the `_content_cache` path.
If `_current_contents` can ever be empty (e.g., no current content for a version), indexing with `[0]` will raise `IndexError`, whereas the previous `qs.first()` would have returned `None`. Consider either guarding against an empty list or replicating the `first()`-style behavior when empty. Also, this early return prevents `_content_cache` from being populated; if you still rely on that cache, assign the object to it before returning to avoid extra queries on subsequent calls.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
djangocms_stories/models.py
Outdated
| if hasattr(self, "_current_contents"): | ||
| return self._current_contents[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Accessing _current_contents[0] can raise on an empty collection and bypasses the _content_cache path.
If _current_contents can ever be empty (e.g., no current content for a version), indexing with [0] will raise IndexError, whereas the previous qs.first() would have returned None. Consider either guarding against an empty list or replicating the first()-style behavior when empty. Also, this early return prevents _content_cache from being populated; if you still rely on that cache, assign the object to it before returning to avoid extra queries on subsequent calls.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #65 +/- ##
==========================================
- Coverage 89.93% 89.84% -0.09%
==========================================
Files 23 23
Lines 2106 2108 +2
Branches 239 240 +1
==========================================
Hits 1894 1894
- Misses 130 131 +1
- Partials 82 83 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary by Sourcery
Optimize story content retrieval when using draft content, especially with djangocms-versioning prefetch caches.
Enhancements: