[Django]-`_get_page` to instantiate the Page class

5đź‘Ť

âś…

It is already in the comment of the function:

def _get_page(self, *args, **kwargs):
    """
    Returns an instance of a single page.

    This hook can be used by subclasses to use an alternative to the
    standard :cls:`Page` object.
    """
    return Page(*args, **kwargs)

Imagine that later you write your own paging method (with a more advanced Page object), then you will need not only to fix all your code by using the new Page object (and perhaps some still need to use the “old” page object), but you would have to patch some parts of the Django codebase as well.

By introducing a method that acts as a wrapper around the Page constructor, we can monkey patch the construction of a page.

For example we can define our own speciale Page class:

class SpecialPage(Page):

    # ...
    pass

and then we can add a monkey_patching.py file to any of the applications, and write:

import django.core.paginator

def _new_get_page(self, *args, **kwargs):
    return SpecialPage(*args, **kwargs)

django.core.paginator._get_page = _new_get_page

Typically by creating “levels of indirection”, one allows a user to fix certain parts at those indirection levels, and thus can inject their own implementation into Django parts.

Subclassing is the most straightforward fix, but not per se the only one. Perhaps you want to preprocess certain arguments, or post-process the Page object, or fire some “signals” to all kind of functions that do something with the Page that is created. Perhaps for a page those are not very logical things, but for other object constructions (like model instances), adding those levels of indirection are more sensical.

4đź‘Ť

The advantage is, like the docstring says (that you also show in your question):

This hook can be used by subclasses to use an alternative to the standard :cls:Page object.

If we just want to change the Page class, we override _get_page() but don’t need to repeat the whole logic that builds top and bottom parameters in the page() method (DRY principle).

We would override the page() method only if we want to change some part of the logic calculated in there.

👤Ralf

Leave a comment