Skip to content

Conversation

@fsbraun
Copy link
Member

@fsbraun fsbraun commented Nov 6, 2025

Summary by Sourcery

Enable explicit site-based filtering throughout Story models and utilities by accepting a Site instance in manager methods and ensuring compatibility with various django CMS versions.

Enhancements:

  • Refactor tag_cloud, SiteQuerySet.on_site, filter_by_language, and get_months methods to accept a Site instance instead of a boolean flag
  • Introduce site_compatibility_decorator to adapt get_current_site for older and newer django CMS versions
  • Update view mixins and CMS menu integration to retrieve the current site from request and pass it to on_site calls

Tests:

  • Revise existing tests to pass explicit Site objects to on_site and get_months methods
  • Adjust tag_cloud tests to use the new site parameter for site-based filtering

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 6, 2025

Reviewer's Guide

This PR refactors site detection to be request-based by overhauling manager and queryset APIs to accept explicit Site parameters, updates corresponding tests, introduces a compatibility decorator for get_current_site, and revises views and CMS menus to leverage the new request-aware site filtering.

Sequence diagram for request-based site detection in views and menus

sequenceDiagram
    participant actor User
    participant View
    participant "get_current_site"
    participant QuerySet
    User->>View: Sends HTTP request
    View->>"get_current_site": Passes request
    "get_current_site"->>View: Returns Site
    View->>QuerySet: Calls on_site(site)
    QuerySet->>View: Returns filtered queryset
    View->>User: Returns response
Loading

Class diagram for updated SiteQuerySet and manager methods

classDiagram
    class SiteQuerySet {
        +on_site(site: Site) : SiteQuerySet
        +filter_by_language(language, site: Site | None = None) : SiteQuerySet
    }
    class PostContentManager {
        +filter_by_language(language, site: Site | None = None)
        +on_site(site: Site | None = None)
        +get_months(queryset=None, site: Site | None = None)
    }
    SiteQuerySet <|-- PostContentManager
    class TagManager {
        +tag_cloud(other_model=None, queryset=None, published: bool = True, site: Site | None = None)
    }
Loading

Flow diagram for site_compatibility_decorator logic

flowchart TD
    A["site_compatibility_decorator(func)"] --> B["Try: func(None)"]
    B --> C["TypeError? -> Return lambda request: func()"]
    B --> D["ImproperlyConfigured? -> Return func"]
    B --> E["Else: Return func"]
Loading

File-Level Changes

Change Details Files
Refactor manager and queryset methods for explicit site filtering
  • tag_cloud now accepts a Site instance and invokes queryset.on_site(site)
  • SiteQuerySet.on_site signature updated to require a Site argument
  • filter_by_language and get_months methods refactored to take an optional site parameter
  • Manager proxy methods forward the site parameter to the underlying queryset methods
djangocms_stories/managers.py
Adjust tests to pass explicit Site instances
  • Replace bare on_site() calls with on_site(Site.objects.get_current())
  • Update get_months invocations to supply site or None instead of boolean flag
  • Modify tag_cloud test to use the new site parameter
tests/test_managers.py
Add site_compatibility_decorator for get_current_site compatibility
  • Introduce a decorator to wrap get_current_site and handle TypeError/ImproperlyConfigured
  • Import ImproperlyConfigured and return appropriate wrapper based on function signature
djangocms_stories/utils.py
Integrate request-based site detection in views and CMS menus
  • Apply site_compatibility_decorator to get_current_site in views
  • Retrieve the current site from the request and pass it to queryset .on_site calls
  • Update cms_menus logic to obtain site via get_current_site(request) before filtering
djangocms_stories/views.py
djangocms_stories/cms_menus.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a 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:

  • The site_compatibility_decorator currently invokes the wrapped function at import time and doesn't preserve metadata—consider using functools.wraps and inspect.signature to detect the expected parameters instead of a trial call.
  • Several manager methods still reference legacy flags in their docstrings; please update the documentation to reflect the new 'site' parameter and its behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The site_compatibility_decorator currently invokes the wrapped function at import time and doesn't preserve metadata—consider using functools.wraps and inspect.signature to detect the expected parameters instead of a trial call.
- Several manager methods still reference legacy flags in their docstrings; please update the documentation to reflect the new 'site' parameter and its behavior.

## Individual Comments

### Comment 1
<location> `tests/test_managers.py:233-238` </location>
<code_context>
         """Test get_months filters by current site"""
-        months = Post.objects.get_months(current_site=True)
+        site = Site.objects.get_current()
+        months = Post.objects.get_months(site=site)

         assert isinstance(months, list)
</code_context>

<issue_to_address>
**suggestion (testing):** Add assertions to verify that months are correctly filtered by site.

Add assertions to confirm that each month in the result matches posts from the specified site, ensuring the filter works as intended.

```suggestion
    def test_get_months_with_current_site(self, page_with_menu, many_posts):
        """Test get_months filters by current site"""
        site = Site.objects.get_current()
        months = Post.objects.get_months(site=site)

        assert isinstance(months, list)
        # Assert that each month in the result matches posts from the specified site
        for year, month in months:
            posts_in_month = Post.objects.filter(
                site=site,
                publish_date__year=year,
                publish_date__month=month
            )
            assert posts_in_month.exists()
            for post in posts_in_month:
                assert post.site == site
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov
Copy link

codecov bot commented Nov 6, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.67%. Comparing base (166a805) to head (5e6425d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
djangocms_stories/utils.py 66.66% 3 Missing ⚠️
djangocms_stories/managers.py 75.00% 1 Missing and 1 partial ⚠️
djangocms_stories/cms_menus.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #56      +/-   ##
==========================================
+ Coverage   86.57%   86.67%   +0.10%     
==========================================
  Files          23       23              
  Lines        2070     2071       +1     
  Branches      232      230       -2     
==========================================
+ Hits         1792     1795       +3     
+ Misses        186      183       -3     
- Partials       92       93       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@fsbraun fsbraun merged commit bc4bb04 into main Nov 6, 2025
21 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants