Sequence Template Integration

Developer guide for the Enezaframework sequence generation. Part of the Sequence Generation series.

Table of Contents

  1. Overview
  2. get_sequence_format()
  3. Admin Template Preview
  4. Form Validation and Saving
  5. Related Guides

Overview

Sequence generation is a backend concern, but the config model exposes one display helper that admin and templates use to preview the expected format. This page covers that helper and the save-time validation that guarantees the field is populated.


get_sequence_format()

SequenceConfig.get_sequence_format() (enezaframework/models/enezasequence.py:25-27) returns the format string with # standing in for each digit:

python
def get_sequence_format(self):
    formatted_number = '#' * self.number_length
    return f"{self.prefix}{self.delimiter}{formatted_number}"
Config Result
prefix CUST, delimiter -, length 4 CUST-####
prefix INV, delimiter -, length 5 INV-#####
prefix PO, delimiter /, length 3 PO/###

It is display-only; generation does not call it. The real value comes from generate_sequence().


Admin Template Preview

Because the method takes no arguments, call it without parentheses in Django templates:

html
<!-- In a sequence admin/change template -->
<div class="sequence-preview">
    <strong>Expected Format:</strong>
    <code>{{ sequence_config.get_sequence_format }}</code>
</div>
flowchart LR
    CFG["SequenceConfig<br/>prefix=CUST, delimiter=-, length=4"] --> FMT["get_sequence_format"]
    FMT --> OUT["CUST-####"]
    OUT --> TMPL["Admin template"]

Form Validation and Saving

The mixin validates at save time rather than in a form. The relevant logic (enezaframework/services/Mixin.py:30-45):

python
def save(self, *args, **kwargs):
    sequence_field_name = self.sequence_field_name
    currentobject = self.__class__.objects.filter(pk=self.pk)

    if not currentobject:
        if not getattr(self, sequence_field_name, None):
            sequence_value = self.generate_sequence()
            if not sequence_value:
                raise ValueError(
                    f"Failed to generate sequence for field '{sequence_field_name}' in model '{self.__class__.__name__}'."
                )
            setattr(self, sequence_field_name, sequence_value)

    super().save(*args, **kwargs)

Implications for forms and templates:

  • A form field for the sequence number can be left blank on create; the mixin fills it.
  • If you want to show the number on a create form, it will not exist until after save. Generate on save, then redirect to the detail page to display it.
  • Supplying a manual value disables generation for that record.

If the field must appear read-only on a detail view, expose it as a normal model field — it is populated by the time the record is read back.