Party Inline System

Developer guide for the Enezaframework party system. Part of the Party System series.

Table of Contents

  1. Overview
  2. Static Inlines
  3. Conditional Inlines
  4. Party Inline Views
  5. How Inlines Are Injected
  6. Party PK Resolution in URLs
  7. Related Guides

Overview

When a model inherits PartyModelMixin, its detail page automatically displays party inlines — no get_inline_related_objects() override needed. The framework inspects the model for a party FK to Party (BaseDetailView._is_party_based_model(), enezaframework/views/base.py:200-208) and injects the appropriate inline dictionaries.

There are two kinds of inline:

  • Static — always shown for any party type (Address, Contact Information).
  • Conditional — shown based on the party's party_type (Personal Details for PRS, Business Details for ORG).

Static Inlines

Inline Model Relation Template
Address Address FK to Party (addresses) inline_list_add_con_partial.html
Contact Information ContactInformation FK to Party (contact_information) inline_list_add_con_partial.html

Both are one-to-many lists.


Conditional Inlines

Party type Inline Model Relation Template
PRS (Person) Personal Details Person OneToOne to Party (person_profile) detail_party_one_on_one.html
ORG (Organization) Business Details Business OneToOne to Party (business_profile) detail_party_one_on_one.html

The framework builds the conditional list and keeps only the entries whose condition matches the party's type (enezaframework/views/base.py:241-276):

python
party_type = party.party_type
matched_conditionals = [
    obj for obj in conditional_inlines
    if obj.get('condition') == party_type
]
return matched_conditionals + static_inlines

If no party is linked yet (self.object.party is None), the framework returns an empty inline list — there is nothing to attach the inlines to.


Party Inline Views

The party inlines do not live in your app. They are shared views in enezacommon/views/party_views.py, with parent_model = Party and main_object_pk set to the Party's primary key.

View Model related_name
PartyAddresslistView Address addresses
PartyAddressdetailView Address addresses
PartyAddressCreateView Address addresses
PartyAddressDeleteView Address addresses
PartyContactInformationlistView ContactInformation contact_information
PartyContactInformationDetailView ContactInformation contact_information
PartyContactInformationCreateView ContactInformation contact_information
PartyContactInformationDeleteView ContactInformation contact_information
PartyPersonView Person person_profile
PartyBusinessView Business business_profile

Because parent_model is Party, these views resolve party_object from main_object_pk and use {{ party_object.pk }} in their templates. See Party Template Context.


How Inlines Are Injected

flowchart TD
    REQ[Detail page request] --> CTX["BaseDetailView.get_context_data()"]
    CTX --> PARTY["party_object = object.party"]
    PARTY --> EXISTS{"party set?"}
    EXISTS -->|No| EMPTY[No party inlines]
    EXISTS -->|Yes| STATIC["Append Address + ContactInformation"]
    EXISTS -->|Yes| TYPE{"party_type"}
    TYPE -->|PRS| PERSON["Append Person inline"]
    TYPE -->|ORG| BUSINESS["Append Business inline"]
    STATIC --> FLAG["Mark each with is_party_inline=True"]
    PERSON --> FLAG
    BUSINESS --> FLAG
    FLAG --> RENDER["Render in detail_partial.html<br/>via inline_items_section.html"]

The injected dictionaries carry is_party_inline: True, plus the model, app, relation_name, and either a condition (conditional) or no condition (static).


Party PK Resolution in URLs

The parent detail template includes inline_items_section.html, which chooses the object ID for each inline URL:

html
hx-get="{% url inline_item.app|default:current_app|add:':'|add:inline_item.url inline_item.related_object_id %}?main_object_pk={% if inline_item.is_party_inline %}{{party_object.pk}}{% else %}{{object.id}}{% endif %}"
flowchart LR
    ITEM[inline_item] --> FLAG{"is_party_inline?"}
    FLAG -->|Yes| PPK["main_object_pk = party_object.pk"]
    FLAG -->|No| OPK["main_object_pk = object.id"]
    PPK --> PVIEW[Party inline view<br/>parent_model = Party]
    OPK --> NVIEW[App inline view<br/>parent_model = your model]
  • Party inlines pass the Party PK, so the shared party views can filter Address/ContactInformation/Person/Business by party.
  • Non-party inlines pass the parent object PK as before.

For one-to-one conditionals, the inline's related_object_id is resolved through the party chain by BaseDetailView._get_party_related_object_id() (enezaframework/views/base.py:278-288).