Django-Forkit is composed of a set of utility functions for forking, resetting, and diffing model objects. Below are a list of the current utility functions:
Creates and returns a new object that is identical to reference
.
fields
- A list of fields to fork. If a falsy value, the fields will be inferred depending on the value ofdeep
.exclude
- A list of fields to not fork (not applicable iffields
is defined)deep
- IfTrue
, traversing all related objects and creates forks of them as well, effectively creating a new tree of objects.commit
- IfTrue
, all forks (including related objects) will be saved in the order of dependency. IfFalse
, all commits are stashed away until the root fork is committed.**kwargs
- Any additional keyword arguments are passed along to all signal receivers. Useful for altering runtime behavior in signal receivers.
fork(reference, [fields=None], [exclude=('pk',)], [deep=False], [commit=True], [**kwargs])
Same parameters as above, except that an explicit instance
is rquired and
will result in an in-place update of instance
. For shallow resets, only the
local non-relational fields will be updated. For deep resets, direct
foreign keys will be traversed and reset. Many-to-many and reverse foreign keys
are not attempted to be reset because the comparison between the related objects
for reference
and the related objects for instance
becomes ambiguous.
reset(reference, instance, [fields=None], [exclude=('pk',)], [deep=False], [commit=True], [**kwargs])
Commits any unsaved changes to a forked or reset object.
commit(reference, [**kwargs])
Performs a diff between two model objects of the same type. The output is a
dict
of differing values relative to reference
. Thus, if
reference.foo
is bar
and instance.foo
is baz
, the output will
be {'foo': 'baz'}
. Note: deep diffs only work for simple non-circular
relationships. Improved functionality is scheduled for a future release.
diff(reference, instance, [fields=None], [exclude=('pk',)], [deep=False], [**kwargs])
Also included is a Model
subclass which has implements the above functions
as methods.
from forkit.models import ForkableModel
class Author(ForkableModel):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
Let's create starting object:
author = Author(first_name='Byron', last_name='Ruth')
author.save()
To create copy, simply call the fork
method.
author_fork = author.fork()
When an object is forked, it immediately inherits it's data including related objects.
author_fork.first_name # Byron
author_fork.last_name # Ruth
Let us change something on the fork and use the diff
method to compare it
against the original author
. It returns a dictionary of the differences
between itself and the passed in object.
author_fork.first_name = 'Edward'
author_fork.diff(author) # {'first_name': 'Edward'}
Once satisfied with the changes, simply call commit
.
author_fork.commit()
For each of the utility function above, pre_FOO
and post_FOO
signals
are sent allowing for a decoupled approached for customizing behavior, especially
when performing deep operations.
sender
- the model class of the instancereference
- the reference object the fork is being created frominstance
- the forked object itselfconfig
- adict
of the keyword arguments passed intoforkit.tools.fork
sender
- the model class of the instancereference
- the reference object the fork is being created frominstance
- the forked object itself
sender
- the model class of the instancereference
- the reference object the instance is being reset relative toinstance
- the object being resetconfig
- adict
of the keyword arguments passed intoforkit.tools.reset
sender
- the model class of the instancereference
- the reference object the instance is being reset relative toinstance
- the object being reset
sender
- the model class of the instancereference
- the reference object the instance has been derivedinstance
- the object to be committed
sender
- the model class of the instancereference
- the reference object the instance has been derivedinstance
- the object that has been committed
sender
- the model class of the instancereference
- the reference object the instance is being diffed againstinstance
- the object being diffed withconfig
- adict
of the keyword arguments passed intoforkit.tools.diff
sender
- the model class of the instancereference
- the reference object the instance is being diffed againstinstance
- the object being diffed withdiff
- the diff between thereference
andinstance