Skip to main content

Presenter pattern to help manage the complexity of bloated controllers/views and logic-laden templates

Project description

Python Presenter

Overview

The Python Presenter is a library designed to address common architectural challenges in web application development by introducing a flexible, testable layer between application logic and presentation. Inspired by architectural patterns that separate concerns, this library provides a robust solution for managing view-specific logic and data preparation.

The Problem

As web applications grow in complexity, developers often encounter several architectural challenges:

  1. Logic Complexity: Application logic becomes increasingly complex, handling multiple responsibilities.
  2. Presentation Logic Creep: Template files begin to contain formatting, computation, and business logic.
  3. Testing Difficulties: Complex logic becomes challenging to test in isolation.

The Presenter Solution

The Python Presenter library introduces a dedicated layer that:

  • Encapsulates presentation-specific data preparation
  • Separates concerns between data retrieval and presentation
  • Provides a clean, testable interface for presentation logic
  • Simplifies application logic responsibilities

Key Benefits

  • Improved Testability: Logic can be unit tested without setting up complex application environments
  • Separation of Concerns: Cleanly separates data aggregation from presentation
  • Flexible Architecture: Easily extensible to handle complex presentation requirements
  • Enhanced Maintainability: Reduces complexity in application logic and templates

Installation

pip install python-presenter

Basic Usage

Simple Example

In your module, define a presenter.py file, and map the model datapoints you want extensively.

# presenter.py
from python_presenter import BasePresenter as base_presenter

class ProjectPresenter(base_presenter):
    def price_detail(self):
        return self.obj.price_detail

    def project_name(self):
        return self.obj.project_name

    def property_address(self):
        return self.obj.property_address

    def property_unit_type(self):
        result = self.obj.property_unit_type
        return property_types[result].value if result in property_types.__members__ else result

    @property
    def labels(self):
        return {
            'price_detail': 'Price Detail',
            'project_name': 'Project Name',
            'property_address': 'Property 7 Address', # you can author labels to be different from database column labels on the fly.
            'property_unit_type': 'Property Unit Type',
        }

This defines the specific object you want to render on the HTML template. Any data from the database that is not explicitly defined here will not appear on the template when using {% present_object model_name_or_app_name %} in the template file. This approach allows you to preprocess and customize the data before presenting it in the template, keeping the logic out of the template itself. Additionally, it provides an opportunity to test the object at the code level, ensuring better maintainability and separation of concerns.

Django Templating:

The presenter_tag is provided as a template tag to render objects using a specified presenter class. To use it, include the tag in your template with {% load presenter_tag %}. Then, use the predefined present_object method to render the objects defined in the presenter file you created. See below:

<!-- templates/whatever_template_file.html -->

{% extends "base.html" %}
{% load static %}

{% load presenter_tag %}

{% block content %}
    {% for project in projects %}
        {% present_object project as presented_project %}
            <li><strong>{{ presented_project.labels.price_detail }}:</strong> {{ presented_project.price_detail }}</li>
            <li><strong>{{ presented_project.labels.project_name }}:</strong> {{ presented_project.project_name }}</li>
            <li><strong>{{ presented_project.labels.expected_profit }}:</strong> {{ presented_project.expected_profit }}</li>
            <li><strong>{{ presented_project.labels.property_address }}:</strong> {{ presented_project.property_address }}</li>
            <li><strong>{{ presented_project.labels.property_unit_type }}:</strong> {{ presented_project.property_unit_type }}</li>
            <br><br>
            <!-- Other project details -->
    {% endfor %}
{% endblock %}

Flask Templating:

To be added soon!

When to Use

Consider using the Presenter pattern when your application requires:

  • Complex data aggregation from multiple models
  • Significant presentation-specific transformations
  • Consolidated validation across multiple models
  • Improved separation of concerns

Advanced Features

  • Error collection and merging
  • Complex data transformations
  • Presentation-specific computations and formatting

Contributing

We welcome contributions! Please see our contributing guidelines for more information.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgments

Inspired by architectural patterns that emphasize separation of concerns.

Mentions

Many thanks to JetBrains for supplying me with a license to use their product in the development of this tool.

JetBrains

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_presenter-0.1.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

python_presenter-0.1.0-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file python_presenter-0.1.0.tar.gz.

File metadata

  • Download URL: python_presenter-0.1.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.11.5

File hashes

Hashes for python_presenter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6e8ecc7eb17eb8c9c163186a87a5d6d728c32181f862908274812cb8c5139fc2
MD5 259634bad67f617e5b621f144436774b
BLAKE2b-256 e1a1a282a006e11975198a5a73cd21238eff8df46b9573e55e40ad2c7506e643

See more details on using hashes here.

File details

Details for the file python_presenter-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for python_presenter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 458d733cf9f1e5caa137a500342cb8171d2fbe5bdaecb70e708c2fc2d171961c
MD5 f13865d378bdb6f52de10942498e705f
BLAKE2b-256 6579c64b7526ce636f2e6cae3d7eaba9fe4f06f396c520b811d0b9e1e45e6d2b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page