Models

django-anysign presumes digital signature involves models in the Django project: one to store the signatures, another to store signers, and one to store backend specific options.

That said, django-anysign does not embed concrete models: it provides base models you have to extend in your applications. This design allows you to customize models the way you like, i.e. depending on your use case.

Minimal integration

Here is the minimal integration you need in some models.py:

from django_anysign import api as django_anysign


class SignatureType(django_anysign.SignatureType):
    pass


class Signature(django_anysign.SignatureFactory(SignatureType)):
    pass


class Signer(django_anysign.SignerFactory(Signature)):
    pass

The example above is taken from django-anysign‘s Demo project.

SignatureType

class django_anysign.models.SignatureType(*args, **kwargs)

Bases: django.db.models.base.Model

Abstract base model for signature type.

A signature type encapsulates backend setup. Typically:

  • a “configured backend” is a backend class (such as DummySignBackend) and related configuration (URL, credentials...).
  • a Signature instance will be related to a configured backend, via a SignatureType.
signature_backend_code

Machine-readable code for the backend. Typically related to settings, by default keys in settings.ANYSIGN['BACKENDS'] dictionary.

class Meta
abstract = False
SignatureType.signature_backend_options

Dictionary for backend’s specific configuration.

Default implementation returns empty dictionary.

There are 2 main ways for you to setup backends with the right arguments:

  • in the model subclassing this one, override this property. This is the good option if you can have several SignatureType instances for one backend, i.e. if signature_backend_code is not unique.
  • in the backend’s subclass, make __init__() read the Django settings or environment. This can be a good option if you have an unique SignatureBackend instance matching a backend (signature_backend_code is unique).
SignatureType.get_signature_backend()

Instanciate and return signature backend instance.

Default implementation uses get_backend_instance() with signature_backend_code as positional arguement and with signature_backend_options() as keyword arguments.

SignatureType.signature_backend

Return backend from internal cache or new instance.

If signature_backend_code changed since the last access, then the internal (instance level) cache is invalidated and a new instance is returned.

Signature

django_anysign.models.SignatureFactory(SignatureType)

Return base class for signature model, using SignatureType model.

This pattern is the best one we found at the moment to have an abstract base model SignatureBase with appropriate foreign key to SignatureType model. Feel free to propose a better option if you know one ;)

Here is what you get in the Demo project:

class django_anysign_demo.models.Signature(id, signature_type, signature_backend_id, anysign_internal_id)

Bases: django_anysign.models.Signature

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Signature.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Signature.id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

Signature.objects = <django.db.models.manager.Manager object>
Signature.signature_type

Accessor to the related object on the forward side of a many-to-one or one-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

child.parent is a ForwardManyToOneDescriptor instance.

Signature.signers

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

Signer

django_anysign.models.SignerFactory(Signature)

Return base class for signer model, using Signature model.

This pattern is the best one we found at the moment to have an abstract base model Signer with appropriate foreign key to Signature model. Feel free to propose a better option if you know one ;)

Here is what you get in the Demo project:

class django_anysign_demo.models.Signer(id, signature, signing_order, signature_backend_id, anysign_internal_id)

Bases: django_anysign.models.Signer

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Signer.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Signer.id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

Signer.objects = <django.db.models.manager.Manager object>
Signer.signature

Accessor to the related object on the forward side of a many-to-one or one-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

child.parent is a ForwardManyToOneDescriptor instance.