2.10.7 Models

The FrameWork module holds the Model classes (apart from holding the BaseController class as well). As discussed before, the Model class provides a mechanism for updating the user interface based on changed performed in the model instance.

This is a powerful mechanism that allows you to guarantee that the interface is always up-to-date with relation to an instance; it should be used with care, however, because the update semantics are not trivial to understand - just imagine having custom callbacks that alter the same attribute as the proxy callback and you will understand why it is easy to get in recursive loops. This tip I can offer you, therefore: avoid altering the model in custom callbacks, and only do it in special situations.

You can also attach multiple proxies to the same model and have them update automatically; the next section will discuss this further. Before passing on to that, however, I need to describe a special Model called PickledModel. To demonstrate by example, I will revisit the first example we saw in this text, the Person editor from section 2. Let's see the code again:

Looking at the code, you might notice three special issues:

  1. The class our model inherits from is FrameWork.PickledModel.
  2. We actually get our model instance by making a call to Framework.unpickle_model(), passing the class Person as an argument.
  3. We call person.save() at the end of the program.

PickledModel offers a very cheap way to offer persistence for your model instances. If you are familiar with the ZODB, think of PickledModel as a cheapo implementation that allows you to save and restore an instance. To use it:

  1. Have your model class inherit from PickledModel.

  2. Use the unpickle_model function as a "factory" function; it takes the your model's class as the first parameter, and a filename as the optional second parameter (if omitted, it uses the name of the class, with an extension of ".pickle"). The function will try and load the model state from a pickle file, and if it doesn't exist, will create a new model and return it to you. If the pickle file is damaged, it will save it with the extension ".err" (avoiding it being erased by an unwitting save() call).

  3. Use the save() method to save the pickle when you are ready. You may specify a filename to it; otherwise, it uses the default filename specified through the set_pickle() method. Note that unpickle_model makes the filename it tried to used the default by calling set_pickle() internally.

The diary3.py example in examples/Diary/ uses pickling in a more involved manner and is recommended as a reference.