signoffs.core.models.fields#
Custom model fields and relation descriptors
Module Contents#
Classes#
Descriptor that provides a Signoff backed by a OneToOneField to a Signet model, with services to manage the relation on the defining model. Class access yields the Signoff Type class. Instance access yields a Signoff instance wrapping the related Signet object (which may be None, i.e. unsigned Signoff) |
|
A normal OneToOneField with a signoff id so its type can be determined before it is assigned a value |
|
A descriptor that injects a âreverse relationâ manager, filtered for the specific Signoff type. The signoff_type MUST be backed by a Signet with a FK relation to the owning model signet_set_accessor is a string with a path to the reverse relation manager on the owning model - it may use â__â to traverse relations and include method calls e.g., âmy_signet_manager__get_signet_setâ |
|
Descriptor that provides an Approval backed by a OneToOneField to a Stamp model, with services to manage the relation on the defining model. Class access yields the Approval Type class. Instance access yields an Approval instance wrapping the related Stamp object (which will be created if it doesnât yet exist, i.e. uninitiated Approval) |
|
A descriptor that injects a âreverse relationâ manager, filtered for the specific Approval Type. The approval_type MUST be backed by a Stamp with a FK relation to the owning model |
Functions#
Convenience method for constructing from minimal inputs: (1) a sensible OneToOneField(signoff_type.signetModel); and (2) an RelatedSignoffDescriptor(signoff_type) signoff_type may be a Signoff Type or a registered(!) signoff id. Default parameter rationale: null=True, on_delete=SET_NULL make sensible defaults for a Signet relation since presence/absence is semantic; think twice before using other values! reverse related_name from Signet generally not so useful, consider disabling with â+â |
|
A thin wrapper for SignoffSet that configures the correct SignoffSetManager for a single signoff |
|
A thin wrapper for SignoffSet that configures the correct signet_set_accessor for Approvals |
|
A thin wrapper for SignoffSet that configures the correct signet_set_accessor for a single Approval signoff |
|
Convenience method for constructing from minimal inputs: (1) a sensible OneToOneField(approval_type.stampModel); and (2) an RelatedApprovalDescriptor(approval_type) approval_type may be an Approval Type or a registered(!) approval id. Default parameter rationale: null=True, on_delete=SET_NULL make sensible defaults, as a deleting an approval Stamp should not cascade to its âownerâ and the stamp is simply re-created on next access; think twice before using other values! related_name defines âreverse relationâ from Stamp to the approval subject (object declaring the ApprovalField) this is not used internally, but could be very useful e.g., when approval permissions need context of subject Wanrning: the name of this field needs to be unquie for each ApprovalField |
API#
- class signoffs.core.models.fields.RelatedSignoffDescriptor(signoff_type, signet_field)[source]#
Descriptor that provides a Signoff backed by a OneToOneField to a Signet model, with services to manage the relation on the defining model. Class access yields the Signoff Type class. Instance access yields a Signoff instance wrapping the related Signet object (which may be None, i.e. unsigned Signoff)
Initialization
Manage a OneToOne signet_field using the given Signoff Type (or signoff id str)
- __set_name__(owner, name)[source]#
Grab the field named used by owning class to refer to this descriptor
Raises ImproperlyConfigured if the signet_field model relation is not same as the signoff_type Signet model
- class signoffs.core.models.fields.SignoffOneToOneField(*args, signoff_id, **kwargs)[source]#
Bases:
django.db.models.OneToOneFieldA normal OneToOneField with a signoff id so its type can be determined before it is assigned a value
Initialization
- signoffs.core.models.fields.SignoffField(signoff_type, on_delete=models.SET_NULL, null=True, related_name='+', **kwargs)[source]#
Convenience method for constructing from minimal inputs: (1) a sensible OneToOneField(signoff_type.signetModel); and (2) an RelatedSignoffDescriptor(signoff_type) signoff_type may be a Signoff Type or a registered(!) signoff id. Default parameter rationale: null=True, on_delete=SET_NULL make sensible defaults for a Signet relation since presence/absence is semantic; think twice before using other values! reverse related_name from Signet generally not so useful, consider disabling with â+â
In the example::
from signoffs.signoffs import SimpleSignoff applicant_signoff = SimpleSignoff.register('myapp.signoff.applicant', ...) # the verbose / explicit way... class Application(models.Model): # ... applicant_signet = OneToOneField(applicant_signoff.signetModel, on_delete=models.SET_NULL, signoff_type=applicant_signoff, null=True, ) applicant_signoff = RelatedSignoffDescriptor(applicant_signoff, applicant_signet) # the concise convenient way... class Application(models.Model): # ... applicant_signoff, applicant_signet = SignoffField(applicant_signoff)In either case above:
Application.applicant_signetis a ânormalâ One-to-One relation to the Signet modelApplication().applicant_signetis a Signet instance or None (if signoff is not signed)``Application.applicant_signoff`` is a RelatedSignoffDescriptor that ultimately injects a Signoff instance ``Application().applicant_signoff`` is a Signoff instance of the given signoff_type backed by the applicant_signet relation. This Signoff will update the instance's applicant_signet relation whenever it is save()'ed
- class signoffs.core.models.fields.SignoffSet(signoff_type: Union[str, Type[signoffs.core.signoffs.AbstractSignoff]] = None, signet_set_accessor='signatories', signoff_set_manager=None, **kwargs)[source]#
A descriptor that injects a âreverse relationâ manager, filtered for the specific Signoff type. The signoff_type MUST be backed by a Signet with a FK relation to the owning model signet_set_accessor is a string with a path to the reverse relation manager on the owning model - it may use â__â to traverse relations and include method calls e.g., âmy_signet_manager__get_signet_setâ
In the example::
class VacationSignet(AbstractSignet): vacation = models.ForeignKey(Vacation, on_delete=models.CASCADE, related_name='signatories') class Vacation(models.Model): employee = models.CharField(max_length=128) # ... hr_signoffs = SignoffSet('test_app.hr_signoff') mngr_signoffs = SignoffSet('test_app.mngr_signoff')Vacation.signatoriesis the ânormalâReverseManyToOneDescriptorinstance to access the related Signets.Vacation.hr_signoffsandVacation.mngr_signoffsare 2 distinct Signoff Types (Signoff sub-classes), whileVacation().hr_signoffsandVacation().mngr_signoffsare SignoffSetManager instances used to access the set of signoffs of that particular type, backed by the vacation instance.signatories.See managers.SignoffSetManager for access API.
Initialization
Inject a Signoff; kwargs passed directly through to AbstractSignoff.init id defaults to the descriptor name if not specified
- signoff_set_manager#
None
- __set_name__(owner, name)[source]#
Grab the field named used by owning class to refer to this descriptor
- signoff_type()#
Lazy evaluation for signoff_type to allow all signoffs to register before resolving.
Raises ImproperlyConfigured if the signet_set_accessor is not a relation to a Signet Manager or queryset
- signoffs.core.models.fields.SignoffSingle(*args, **kwargs)[source]#
A thin wrapper for SignoffSet that configures the correct SignoffSetManager for a single signoff
- signoffs.core.models.fields.ApprovalSignoffSet(*args, **kwargs)[source]#
A thin wrapper for SignoffSet that configures the correct signet_set_accessor for Approvals
- signoffs.core.models.fields.ApprovalSignoffSingle(*args, **kwargs)[source]#
A thin wrapper for SignoffSet that configures the correct signet_set_accessor for a single Approval signoff
- class signoffs.core.models.fields.RelatedApprovalDescriptor(approval_type, stamp_field)[source]#
Descriptor that provides an Approval backed by a OneToOneField to a Stamp model, with services to manage the relation on the defining model. Class access yields the Approval Type class. Instance access yields an Approval instance wrapping the related Stamp object (which will be created if it doesnât yet exist, i.e. uninitiated Approval)
Initialization
Manage a OneToOne Stamp field using the given Approval Type or approval id
- __set_name__(owner, name)[source]#
Grab the field named used by owning class to refer to this descriptor
Raises ImproperlyConfigured if the stamp_field model relation is not same as the approval_type Stamp model
- signoffs.core.models.fields.ApprovalField(approval_type, on_delete=models.SET_NULL, null=True, related_name='+', **kwargs)[source]#
Convenience method for constructing from minimal inputs: (1) a sensible OneToOneField(approval_type.stampModel); and (2) an RelatedApprovalDescriptor(approval_type) approval_type may be an Approval Type or a registered(!) approval id. Default parameter rationale: null=True, on_delete=SET_NULL make sensible defaults, as a deleting an approval Stamp should not cascade to its âownerâ and the stamp is simply re-created on next access; think twice before using other values! related_name defines âreverse relationâ from Stamp to the approval subject (object declaring the ApprovalField) this is not used internally, but could be very useful e.g., when approval permissions need context of subject Wanrning: the name of this field needs to be unquie for each ApprovalField
In the example::
from signoffs.approvals import ApprovalSignoff from signoffs.models import ApprovalSignet, Stamp @register(id=myapp.application_approval) class ApplicationApproval(ApprovalSignoff): stampModel = Stamp S = ApprovalSignoff reg_signoff = S.register('application.approval.signoff.registration', ...) deposit_signoff = S.register('application.approval.signoff.deposit', ...) final_approval = S.register('application.approval.signoff.final', ...) signing_order = SigningOrder( pm.InSeries( pm.InParallel( ret_signoff, deposit_signoff, ) final_approval, ) ) # The verbose way: class Application(models.Model): # ... approval_stamp = OneToOneField(ApplicationApproval.stampModel, on_delete=models.SET_NULL, null=True) approval = RelatedApprovalDescriptor(ApplicationApproval, approval_stamp) # The convenient way: class Application(models.Model): # ... approval, approval_stamp = ApprovalField(ApplicationApproval)In both cases above:
Application.approval_stampis a ânormalâ One-to-One relation to the backing Stamp modelApplication().approval_stampis a Stamp instance or None (if approval is not initiated)``Application.approval`` is a RelatedApprovalDescriptor that ultimately injects an ApplicationApproval instance ``Application().approval`` is an ApplicationApproval instance, backed by the OneToOne approval_stamp relation. This approval will update the application's OneToOne relation whenever it is save()'ed
- class signoffs.core.models.fields.ApprovalSet(approval_type: Union[str, Type[signoffs.core.approvals.AbstractApproval]] = None, stamp_set_accessor='stamp_set', **kwargs)[source]#
A descriptor that injects a âreverse relationâ manager, filtered for the specific Approval Type. The approval_type MUST be backed by a Stamp with a FK relation to the owning model
In the example::
class BuildingPermit(AbstractApprovalStamp): building = ForeignKey('Building', related_name='permits') @register(id='myapp.building_approval') class ConstructionApproval(BaseApproval): stampModel = BuildingPermit S = ApprovalSignoff planning_signoff = S.register('building.approval.signoff.planning', ...) electrical_signoff = S.register('building.approval.signoff.electrical', ...) plumbing_signoff = S.register('building.approval.signoff.plumbing', ...) inspection_signoff = S.register('building.approval.signoff.inspection', ...) final_approval = S.register('building.approval.signoff.final', ...) signing_order = SigningOrder( InSeries( planning_signoff, InParallel( electrical_signoff, plumbing_signoff, ) AtLeastN(inspection_signoff, 1), final_approval, ) ) class Building(Model): approvals = ApprovalSet(ConstructionApproval, stamp_set_accessor='permits')BuildingPermit.signatoriesis a ânormalâReverseManyToOneDescriptorinstance to access the related Signets.ConstructionApproval().signing_orderdefines a SigningOrderManager to match pattern with the stampâs signets.Building().approvalsis an ApprovalSetManager instance providing a unified API for accessing the set of approvals, backed by building instance.permits.See ApprovalSetManager for access API.
Initialization
Inject ApprovalSetManager; kwargs passed directly through to ApprovalSetManager.init approval_type may be an Approval Type class or a registered approval id
- __set_name__(owner, name)[source]#
Grab the field named used by owning class to refer to this descriptor
- approval_type()#
Raises ImproperlyConfigured if the stamp_set_accessor is not a relation to a Stamp Manager or queryset