@@ -29,8 +29,9 @@ def test_execution_phases():
2929
3030 1. Definition
3131 2. Construction
32- 3. `Bind`_
33- 4. Traversal (e.g. render to html, respond to ajax, custom report creation)
32+ 3. Refine done
33+ 4. `Bind`_
34+ 5. Traversal (e.g. render to html, respond to ajax, custom report creation)
3435
3536
3637 At definition time we can have just a bunch of dicts. This is really a stacking and merging of namespaces.
@@ -44,8 +45,63 @@ def test_execution_phases():
4445 - invoke any user defined :code:`on_bind` handlers
4546
4647 At traversal time we are good to go and can now invoke the final methods of all objects. We can now render html, respond to ajax, etc.
48+ """
49+
50+
51+ def test_refine_done ():
52+ # language=rst
53+ """
54+ Refine done
55+ -----------
56+
57+ At some point we know that this object has been completely configured.
58+ This is when `refine_done` is either called automatically (for example if
59+ you call `bind()` on an object that hasn't had `refine_done()` called yet),
60+ or you can do it explicitly yourself.
61+
62+ The refine done step does a lot of of the work that is needed for the final
63+ traversal step, so if possible you want to make sure this is done before.
64+ If this step is done on an object that is then kept around, all this work
65+ doesn't need to be redone. Examples of work that is done in this step include
66+ all the application of the `Style`, and pre-sorting out callables and constants.
67+
68+ This is simpler to understand with a concrete example, so let's take a
69+ table of albums that contain the string passed in a query parameter, or
70+ otherwise the letter `x`:
71+ """
4772
73+ albums_with_o = Table (auto__model = Album , rows = lambda request , ** _ : Album .objects .filter (name__icontains = request .GET .get ('q' , 'x' )))
74+
75+ # @test
76+ albums_with_o .bind (request = req ('get' )).render_to_response ()
77+ # @end
78+
79+ # language=rst
80+ """
81+ If you register that to a path with the `.as_view()` method, then
82+ `refine_done` will be called once on first use. You can also explicitly call
83+ `refine_done()` to force this optimization to happen at import time, which
84+ might be preferable to you, especially for views that you know will be called
85+ by all web workers anyway.
86+
87+ If you do this instead:
88+ """
89+
90+ def albums_with_o (request ):
91+ return Table (auto__model = Album , rows = Album .objects .filter (name__icontains = request .GET .get ('q' , 'x' )))
92+
93+ # @test
94+ albums_with_o (req ('get' )).bind (request = req ('get' )).render_to_response ()
95+ # @end
96+
97+ # language=rst
98+ """
99+ The functionality is the same, but since a fresh `Table` is created on
100+ each request, all the work done in the `refine_done` step will have to
101+ be redone each request.
48102
103+ So in general, the FBV style is often easier to reason about when starting
104+ out with iommi, but it has some big downsides on performance.
49105 """
50106
51107
0 commit comments