After reading this thread safety document , I have a feeling that there is something in the documentation, or my reading, or my reasoning.
Let a simple example be given:
class HelloWorldNode(template.Node): def render(self, context): return "O HAI LOL" @register.tag(name="hello_world") def hello_world(parser, tokens): """ Greets the world with wide-eyed awe. """ return HelloWorldNode()
I understood this code to create a new instance of the HelloWorldNode class whenever the hello_world tag is hello_world . Other examples include passing arguments to the constructor, for example:
class HelloWorldNode(template.Node): def __init__(self, message): self.message = message def render(self, context): return "O HAI LOL " + message @register.tag(name="hello_world") def hello_world(parser, tokens): """ Greets the world with wide-eyed awe. """ message = tokens.split_contents()[1] return HelloWorldNode(message)
Thus, when hello_world is executed, a new instance of HelloWorldNode is created, and the instance dictionary has a message attribute. This instance, of course, should only be used to render only this tag instance, since using it for other visualizations means that the data bound to it would be incorrect. If this were not the case, the arguments would be mixed between different uses of the tag.
If you look at other examples from the docs, here is a simplified example here :
def do_current_time(parser, token): tag_name, format_string = token.split_contents() return CurrentTimeNode(format_string[1:-1])
Since this receives data from tokens passed to the function, the only way CurrentTimeNode works is that each instance is created every time do_current_time is do_current_time .
Return to the documentation page where the discord is located. This is bad".
class CycleNode(Node): def __init__(self, cyclevars): self.cycle_iter = itertools.cycle(cyclevars) def render(self, context): return self.cycle_iter.next()
Doc says that two pages using the same tag can then experience race conditions if they both use the same node. I do not understand how the rendering of two templates can share the same instance if they both independently create their own.
How to solve this problem, says the documents look like this:
class CycleNode(Node): def __init__(self, cyclevars): self.cyclevars = cyclevars def render(self, context): if self not in context.render_context: context.render_context[self] = itertools.cycle(self.cyclevars) cycle_iter = context.render_context[self] return cycle_iter.next()
The context.render_context index seems to contain self . The consequence of this should be that self used to identify the instance in one of two ways:
self refers to one particular instance of the class throughout the system.self refers only to this class, and a visualization context is required to refer to an instance
If 1 is true, why not just associate the data with self ?
If 2 is true and the visualization context is βassociated with the template context that is currently being displayed,β how can two instances of the template tag be distinguished on the same page?
Is a Node created individually each time a tag is called? If so, why concurrency problems? If not, why not?