🌐 AI搜索 & 代理 主页
Skip to content

Conversation

@mbienkowsk
Copy link

Trac ticket number

N/A

Branch description

In the section regarding window functions of the models/expressions docs, there's an example of querying for ratings of peer movies. Peers are described as follows:

If a movie's "peers" are described as movies released by the same studio in the
same genre in the same year, this ...

The example uses the release year for ordering and doesn't partition by them, which results in a cumulative query where movies from all years up until the release year of the movie in question are included in the average. Fixed by partitioning by the release year instead of ordering by it.

minimal repro in-memory main.py:

import datetime

import django
from django.conf import settings
from django.db import connection, models
from django.db.models import Avg, F, Window

if not settings.configured:
    settings.configure(
        DATABASES={
            "default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}
        },
        INSTALLED_APPS=["__main__"],
    )
    django.setup()


class Movie(models.Model):
    title = models.CharField(max_length=100)
    studio = models.CharField(max_length=50)
    genre = models.CharField(max_length=50)
    released = models.DateField()
    rating = models.IntegerField()

    class Meta:
        app_label = "__main__"


with connection.schema_editor() as schema_editor:
    schema_editor.create_model(Movie)

Movie.objects.create(
    title="M1", studio="A", genre="Action", released=datetime.date(2020, 1, 1), rating=8
)
Movie.objects.create(
    title="M2",
    studio="A",
    genre="Action",
    released=datetime.date(2020, 6, 1),
    rating=10,
)
Movie.objects.create(
    title="M3", studio="A", genre="Action", released=datetime.date(2021, 1, 1), rating=2
)

docs_qs = Movie.objects.annotate(
    avg=Window(
        expression=Avg("rating"),
        partition_by=[F("studio"), F("genre")],
        order_by="released__year",
    )
)
print("Output of documentation query:")
for m in docs_qs:
    print(f"{m.title} ({m.released.year}): {m.avg:.2f}")


fixed_qs = Movie.objects.annotate(
    avg=Window(
        expression=Avg("rating"),
        partition_by=[F("studio"), F("genre"), F("released__year")],
    )
)

print("\nOutput when partitioning by year:")
for m in fixed_qs:
    print(f"{m.title} ({m.released.year}): {m.avg:.2f}")

output:

Output of documentation query:
M1 (2020): 9.00
M2 (2020): 9.00
M3 (2021): 6.67

Output when partitioning by year:
M1 (2020): 9.00
M2 (2020): 9.00
M3 (2021): 2.00

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • (N/A) I have checked the "Has patch" ticket flag in the Trac system.
  • (N/A) I have added or updated relevant tests.
  • (N/A) I have added or updated relevant docs, including release notes if applicable.
  • (N/A) I have attached screenshots in both light and dark modes for any UI changes.

@github-actions github-actions bot added the no ticket Based on PR title, no linked Trac ticket label Dec 3, 2025
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello! Thank you for your contribution 💪

As it's your first contribution be sure to check out the patch review checklist.

If you're fixing a ticket from Trac make sure to set the "Has patch" flag and include a link to this PR in the ticket!

If you have any design or process questions then you can ask in the Django forum.

Welcome aboard ⛵️!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no ticket Based on PR title, no linked Trac ticket

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant