Model-Level Image Size Definition

Developer guide for the Enezaframework. Part of the architecture series.

Table of Contents

  1. Overview
  2. Model-Level Configuration
  3. Configuration Keys
  4. Multiple Images
  5. Template Integration
  6. Validation and Limits
  7. Related Guides

Overview

Enezaframework lets you define image display sizes directly in the model field definition. A single generic template can then serve many models with different image requirements, because the widget reads the size configuration off the bound field.

flowchart TD
    MODEL[Model field:<br/>ConfigurableImageField<br/>image_size_config] --> FORMFIELD[formfield exposes<br/>image_size_config]
    FORMFIELD --> TAG[Template tag:<br/>is_image_field / smart_field]
    TAG --> WIDGET[image_upload_widget]
    WIDGET --> PREVIEW[Preview + responsive sizing]
    WIDGET --> CLIENT[Client-side validation:<br/>type + size]

Key characteristics:

  • Model-level configuration — sizes are declared next to the field.
  • Unified widget — one component handles new uploads and existing previews.
  • Client-side validation — file type and size are checked before submit.
  • Responsive — desktop and mobile sizes come from the same config.
  • Backward compatible — plain ImageField usage continues to work.

Model-Level Configuration

Import ConfigurableImageField from enezaframework.models and pass image_size_config.

python
from django.db import models
from enezaframework.models import ConfigurableImageField


class Profile(models.Model):
    avatar = ConfigurableImageField(
        upload_to="profile_images/",
        image_size_config={
            "max_height": 200,
            "max_width": 200,
            "mobile_max_height": 150,
            "mobile_max_width": 150,
        },
        verbose_name="Avatar",
    )

    banner = ConfigurableImageField(
        upload_to="banner_images/",
        image_size_config={
            "max_height": 300,
            "max_width": 800,
            "mobile_max_height": 200,
            "mobile_max_width": 600,
        },
        verbose_name="Banner",
    )

ConfigurableImageField subclasses models.ImageField, so all normal ImageField options (upload_to, blank, null, verbose_name, and so on) still apply.


Configuration Keys

image_size_config accepts these keys:

Key Type Description
max_height int Maximum display height in pixels (desktop).
max_width int Maximum display width in pixels (desktop).
mobile_max_height int Maximum display height on mobile.
mobile_max_width int Maximum display width on mobile.

The configuration is validated when the model class is created. Keep the mobile values less than or equal to the desktop values.

The field also exposes helpers:

python
field = Profile._meta.get_field("avatar")
field.has_size_config()   # bool
field.get_size_config()   # copy of the config dict

Multiple Images

For a field that stores several images, use ConfigurableMultipleImageField. It subclasses models.JSONField and stores a list of image paths.

python
from enezaframework.models import ConfigurableMultipleImageField


class Listing(models.Model):
    photos = ConfigurableMultipleImageField(
        upload_to="listing_photos/",
        max_images=5,
        image_size_config={
            "max_height": 400,
            "max_width": 400,
            "mobile_max_height": 250,
            "mobile_max_width": 250,
        },
        verbose_name="Photos",
    )
  • max_images defaults to 5 and may not exceed 20.
  • The default value is an empty list.

Template Integration

Load the form_extras template tags, then render image fields with the dedicated widget.

html
{% load form_extras %}

{% if field|is_image_field %}
    {% image_upload_widget field %}
{% else %}
    {# standard field rendering #}
{% endif %}

Related tags available from enezaframework/templatetags/form_extras.py:

Tag Type Purpose
is_image_field filter True for single image fields.
is_multiple_image_field filter True for multiple image fields.
is_file_field filter True for non-image file fields.
image_upload_widget tag Renders tags/image_upload.html for a single image.
multiple_image_upload_widget tag Renders tags/multiple_image_upload.html.
file_upload_widget tag Renders tags/file_upload.html.
smart_field tag Auto-dispatches to the right widget based on the bound field type.

The simplest integration is usually {% smart_field form "avatar" %}, which selects the correct widget and forwards disabled state automatically.


Validation and Limits

The field validates image_size_config when the model class is defined:

  • Only these keys are allowed: max_height, max_width, mobile_max_height, mobile_max_width.
  • Every value must be a positive integer.
  • Values above 10000 pixels are rejected.
  • mobile_max_height must not exceed max_height, and mobile_max_width must not exceed max_width.

For ConfigurableMultipleImageField, max_images must be a positive integer no greater than 20.

Client-side, the widget validates file type (JPG, PNG, GIF) and file size (2 MB limit) before upload. Server-side validation still applies through the underlying ImageField/form field.

Upstream reference note: the architecture reference points to feature_architecture/feature_architecture_image_size_definition.md, which does not exist in this repository. For related implementation notes see ../feature_architecture/README_IMAGE_SIZE_DEFINITION.md (verify the path before linking) and the feature_Planure/ documents.