PartyModelMixin API Reference
Developer guide for the Enezaframework party system. Part of the Party System series.
Table of Contents
- Overview
- API Table
partyFieldparty_categoryparty_related_nameget_party_defaults()_resolve_party_related_name()- MRO Ordering
- Signal Chain
- Source Map
- Related Guides
Overview
Condensed reference for PartyModelMixin (enezaframework/models/ezaparty.py:5) and the signals that act on it.
API Table
| Attribute / Method | Type | Description |
|---|---|---|
party |
ForeignKey |
Auto-provided FK to Party (null=True, blank=True, on_delete=PROTECT). |
party_category |
property | Must override. Returns 'PRS' or 'ORG' (PartyCategory). Determines Person vs Business. Base value is None. |
party_related_name |
class attr | Optional override. The FK reverse name. Base value is None; default resolves to '%(class)s_party'. |
get_party_defaults() |
method | May override. Returns the dict for Party.objects.create(). Calls super() to inherit entity and party_type. |
_resolve_party_related_name() |
classmethod | Returns the resolved related name. Internal. |
party Field
party = models.ForeignKey(
'enezacommon.Party',
null=True,
blank=True,
on_delete=PROTECT,
related_name='%(class)s_party',
verbose_name="Party",
)
- Nullable and blank, because it is filled by the signal after the first insert.
on_delete=PROTECT: aPartycannot be deleted while a business record still references it.- Hidden from forms by
UiMixin.get_form_class()(enezaframework/views/mixins.py:353-361).
party_category
@property
def party_category(self):
return self.customer_type
Must return PartyCategory.PERSON ('PRS') or PartyCategory.ORGANIZATION ('ORG'). If it returns None, the signal logs a warning and skips party creation. See Party Types & Profiles.
party_related_name
party_related_name = 'billing_customers' # optional
When unset, _resolve_party_related_name() returns '%(class)s_party', giving <modelname>_party (for example contact_party). Override only when you need a custom reverse accessor.
get_party_defaults()
Base implementation (ezaparty.py:21-30):
def get_party_defaults(self):
defaults = {
'party_type': self.party_category,
'display_name': str(self),
'is_active': True,
}
entity = getattr(self, 'entity', None)
if entity:
defaults['entity'] = entity
return defaults
Override pattern:
def get_party_defaults(self):
defaults = super().get_party_defaults()
defaults['display_name'] = self.searchname or self.vendorno or 'Vendor'
return defaults
Always call super() so party_type and entity are preserved.
_resolve_party_related_name()
@classmethod
def _resolve_party_related_name(cls):
return cls.party_related_name or '%(class)s_party'
Internal helper used by the framework. Do not call it from application code.
MRO Ordering
class YourModel(PartyModelMixin, EnezaMaster): # PartyModelMixin FIRST
Place PartyModelMixin before EnezaMaster so the abstract party field is contributed correctly through Django's field resolution.
Signal Chain
flowchart TD
SAVE["YourModel.save() (created=True)"] --> FW["auto_create_party_for_party_model<br/>enezaframework/signals.py:9"]
FW --> GUARD{"PartyModelMixin?<br/>party is None?<br/>party_category set?"}
GUARD -->|Fail| SKIP[Skip]
GUARD -->|Pass| PCREATE["Party.objects.create(**get_party_defaults())"]
PCREATE --> LINK["your_model.party = party<br/>save(update_fields=['party'])"]
LINK --> CSIG["create_org_or_person_profile<br/>enezacommon/signals.py:43"]
CSIG --> BRANCH{"party_type"}
BRANCH -->|PRS| PERSON["Person.objects.get_or_create(party=party)"]
BRANCH -->|ORG| BUSINESS["Business.objects.get_or_create(party=party)"]Source Map
| Concern | Location |
|---|---|
| Mixin definition | enezaframework/models/ezaparty.py |
| Party auto-creation | enezaframework/signals.py:9 |
| Profile auto-creation | enezacommon/signals.py:43 |
| Party context and inline injection | enezaframework/views/base.py:183, 200-294 |
Form party exclusion, inline config |
enezaframework/views/mixins.py:353-361, 894-927 |
| Party bridge | enezaframework/views/baseinline.py:648-693 |
| Shared party models | enezacommon/models/Party.py |
| Party inline views | enezacommon/views/party_views.py |
| Party category choices | enezacommon/models/choices.py:49 |