Party View Layer
Developer guide for the Enezaframework party system. Part of the Party System series.
Table of Contents
- Overview
- What You Do Need to Define
- What You Do Not Need to Define
- What You May Optionally Define
- Adding Your Own Inlines Alongside Party Inlines
- Responsibility Split
- Related Guides
Overview
A party-based model uses the standard CRUD base views. The presence of PartyModelMixin changes nothing about how the views are declared; it only changes what the detail view injects into the page at runtime.
The rule of thumb: declare the same views you would for any other model, and delete any party-specific code you used to write.
What You Do Need to Define
| View | Base class | Required members |
|---|---|---|
| List | BaseListView |
model, set_list_fields(), set_search_fields() |
| Detail | BaseDetailView |
model, detail_ui_view() |
| Create | BaseCreateView |
model, detail_ui_view() |
| Delete | BaseDeleteView |
model |
from enezaframework.views import (
BaseListView, BaseDetailView, BaseCreateView, BaseDeleteView,
)
from enezaframework.utils import auto_url_register
from myapp.models import Customer
@auto_url_register
class CustomerListView(BaseListView):
model = Customer
def set_list_fields(self):
return ['customer_no', 'party', 'customer_type', 'name']
def set_search_fields(self):
return ['customer_no', 'name']
@auto_url_register
class CustomerDetailView(BaseDetailView):
model = Customer
def detail_ui_view(self):
return [
{
'name': 'Basic Information',
'icon': 'Home',
'Fieldcolumns': [
{'fields': ['customer_no', 'customer_type']},
{'fields': ['name', 'email']},
],
},
]
@auto_url_register
class CustomerCreateView(BaseCreateView):
model = Customer
def detail_ui_view(self):
return [
{
'name': 'Basic Information',
'icon': 'Home',
'Fieldcolumns': [
{'fields': ['customer_no', 'customer_type']},
{'fields': ['name', 'email']},
],
},
]
@auto_url_register
class CustomerDeleteView(BaseDeleteView):
model = Customer
What You Do Not Need to Define
Do not write any of the following for a party-based model — the framework already does it:
get_inline_related_objects()—BaseDetailViewauto-injects the party inlines (enezaframework/views/base.py:290-294).get_related_object_id()—InlineMixinresolves the profile IDs through the party chain (enezaframework/views/mixins.py:894-927).- Any logic to create or link the
Party— thepost_savesignal owns it. - A form field for
party—UiMixin.get_form_class()excludes it (enezaframework/views/mixins.py:353-361).
flowchart TD
subgraph You["You write"]
LV[List view + fields]
DV[Detail view + detail_ui_view]
CV[Create view + detail_ui_view]
DEL[Delete view]
end
subgraph Framework["Framework provides"]
P1[party FK field]
P2[Party auto-creation]
P3[Person/Business profile]
P4[Party inlines on detail]
P5[party hidden from forms]
P6[Profile id resolution]
end
LV --> P4
DV --> P4
DV --> P6
CV --> P5What You May Optionally Define
- Additional non-party inlines. Override
get_inline_related_objects(), callsuper()to keep the party inlines, then append your own. See the next section. - Custom one-to-one inline views. If you need your own profile inline view instead of the shared party views, use
BaseInlineOneToOneDetailViewand let the party bridge resolve it. See Party-Bridge Pattern. - Inline detail views for Person/Business. Useful for backward compatibility with pre-existing URLs.
Adding Your Own Inlines Alongside Party Inlines
The base get_inline_related_objects() returns the party inlines. To add regular child inlines without losing them, extend the returned list:
@auto_url_register
class CustomerDetailView(BaseDetailView):
model = Customer
def detail_ui_view(self):
return [
{
'name': 'Basic Information',
'icon': 'Home',
'Fieldcolumns': [
{'fields': ['customer_no', 'customer_type']},
{'fields': ['name', 'email']},
],
},
]
def get_inline_related_objects(self):
inlines = super().get_inline_related_objects()
inlines.append(
{
'name': 'salesorders',
'caption': 'Sales Orders',
'active': 1,
'relation_name': 'sales_orders',
'position': 2,
'icon': 'DocumentPlus',
'model': 'SalesOrder',
'app': 'myapp',
}
)
return inlines
Always call super() first; hard-coding the list replaces the party inlines and silently breaks the party tabs.
See Field & Inline UI Configuration for the full inline dictionary schema.
Responsibility Split
| Task | You | Framework |
|---|---|---|
| Declare the model and fields | Yes | — |
Provide party_category / get_party_defaults() |
Yes | — |
| List/detail/create/delete views | Yes | — |
| Party FK field | — | Yes |
| Party + profile creation | — | Yes |
| Party inlines and their IDs | — | Yes |
Hide party from forms |
— | Yes |
| Extra app-specific inlines | Optional | — |