Architecture#
Unicorn
is made up of multiple pieces which are all integrated tightly together. The following is a summary of how some of it all fits together, although it skips over a lot of the complexity and advanced functionality. However, for all of the details the code is available at https://github.com/adamghill/django-unicorn/.
JavaScript initialization#
After the template is rendered, the JavaScript library parses the HTML for DOM elements that start with unicorn:
or u:
and creates a list of attributes that end with :model
, :poll
, or other specific Unicorn
functionality. For attributes that are left, the assumption is that they are an event type (e.g. unicorn:click
).
For anything that is a model, the JavaScript sets the value for the element based on the serialized data of the publicly available attributes from the component view. Event listeners are attached for all event types. Then, other custom functionality is setup (e.g. polling).
Models#
For all inputs which have a model
attribute, an event listener is attached (either change
or blur
depending on if the lazy
modifier is used). The defer
modifier will store the action to be bundled with an action event that might happen later.
Once a model event is fired it is sent over the wire to the defined AJAX endpoint with a specific JSON structure which tells Unicorn
what the updated data from the input should be. The component class is re-instantiated and the data is updated from the front-end, then re-rendered and the HTML is returned in the response.
Actions#
Actions follow a similar path as the models above, however there is a different JSON stucture. Also, the method, arguments, and kwargs that are passed from the front-end get parsed with a mix of ast.parse
and ast.literal_eval
to convert the strings into the appropriate Python types (i.e. change the string “1” to the integer 1
). After the component is re-initialized, the method is called with the passed-in arguments and kwargs. Once all of the actions have been called, the component view is re-rendered and the HTML is returned in the response.
HTML Diff#
After the AJAX endpoint returns its response, the newly rendered DOM is merged into the old DOM and input values are set again based on the new data in the AJAX response. By default, a library called morphdom
is used to do the diffing and merging of the DOM. However, this can be overridden by setting the MORPHER
setting to use a different library.