Después de leer acerca de la seguridad this document hilo, me dio la sensación de que hay algo que falta en la documentación, o la lectura de la misma, o de mi razonamiento.hilo de seguridad con plantilla Etiquetas
Vamos a dar un ejemplo sencillo:
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()
entendí este código para construir una nueva instancia de la clase HelloWorldNode
cada vez que se utiliza la etiqueta de hello_world
. Otros ejemplos implican el paso de argumentos al constructor, así:
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)
Por lo tanto, cuando se ejecuta hello_world
, se crea una nueva instancia de HelloWorldNode, y el diccionario ejemplo, tiene un atributo message
. Esta instancia seguramente se debe usar solo para la representación de solo la instancia dada de la etiqueta, ya que usarla para otras representaciones significaría que los datos vinculados a ella serían incorrectos. Si este no fuera el caso, los argumentos se mezclarían entre los diferentes usos de la etiqueta.
En cuanto a otros ejemplos de la documentación, aquí hay un ejemplo simplificado de here:
def do_current_time(parser, token):
tag_name, format_string = token.split_contents()
return CurrentTimeNode(format_string[1:-1])
Como esta toma los datos de las fichas pasan a la función, la única manera de que CurrentTimeNode puede funcionar es que uno nuevo se crea una instancia cada vez que se invoca do_current_time
.
Volver a la página de documentación, donde la disonancia fija. Esto es 'malo'.
class CycleNode(Node):
def __init__(self, cyclevars):
self.cycle_iter = itertools.cycle(cyclevars)
def render(self, context):
return self.cycle_iter.next()
El documento dice que dos páginas con la misma etiqueta pueden experimentar condiciones de carrera si ambas usan el mismo nodo. No entiendo cómo la representación dos plantillas podría terminar compartiendo la misma instancia si ambos ejemplifican de forma independiente su propia cuenta.
La manera de resolver esto, dice la documentación es la siguiente:
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()
Esto parece índice context.render_context
con self
. La implicación de que debe ser que self
se utiliza para identificar la instancia de una de dos maneras:
self
referencias una instancia específica de la clase en todo el sistemaself
referencias esa clase única, y con el fin para hacer referencia a la instancia, se requiere un contexto de representación
Si 1 es verdadero, ¿por qué no asociar datos con self
?
Si 2 es verdadero y el contexto de representación está "asociado con el contexto de la plantilla que se está representando actualmente", ¿cómo es posible distinguir entre dos instancias de la etiqueta de plantilla en la misma página?
es el nodo de instancia individualmente cada vez que se invoca la etiqueta? Si es así, ¿por qué los problemas de concurrencia? ¿Si no, porque no?