2011-09-20 48 views
8

Sau khi đọc this document về an toàn luồng, tôi còn lại cảm thấy rằng có điều gì đó bị thiếu trong tài liệu hoặc đọc sách của tôi hoặc lý do của tôi.An toàn Chủ đề với Thẻ Mẫu

Hãy đưa ra một ví dụ đơn giản:

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() 

tôi hiểu mã này để xây dựng một trường hợp mới của lớp HelloWorldNode bất cứ khi nào thẻ hello_world được sử dụng. Những ví dụ khác liên quan đến việc đi qua đối số cho các nhà xây dựng, như thế này:

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) 

Vì vậy, khi hello_world được thực thi, một trường hợp mới của HelloWorldNode được tạo ra, và từ điển dụ có một thuộc tính message. Ví dụ này chắc chắn phải được sử dụng chỉ cho kết xuất của trường hợp được chỉ định của thẻ, như sử dụng nó cho render khác có nghĩa là dữ liệu bị ràng buộc với nó sẽ là không chính xác. Nếu đây không phải là trường hợp, các đối số sẽ bị lẫn lộn giữa các cách sử dụng thẻ khác nhau.

Nhìn vào ví dụ khác từ các tài liệu, đây là một ví dụ đơn giản từ here:

def do_current_time(parser, token): 
    tag_name, format_string = token.split_contents() 
    return CurrentTimeNode(format_string[1:-1]) 

Vì đây mất dữ liệu từ thẻ truyền cho hàm, cách duy nhất mà CurrentTimeNode có thể làm việc là một cái mới được khởi tạo mỗi khi do_current_time được gọi.

Quay lại trang tài liệu, nơi thiết lập sự bất hòa. Đây là 'xấu'.

class CycleNode(Node): 
    def __init__(self, cyclevars): 
     self.cycle_iter = itertools.cycle(cyclevars) 
    def render(self, context): 
     return self.cycle_iter.next() 

Tài liệu nói rằng hai trang sử dụng cùng một thẻ có thể trải nghiệm điều kiện chủng tộc nếu cả hai đều sử dụng cùng một nút. Tôi không hiểu cách hiển thị của hai mẫu có thể kết thúc chia sẻ cùng một trường hợp nếu cả hai đều tự khởi tạo riêng.

Cách giải quyết này, cho biết các tài liệu là như thế này:

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() 

này dường như chỉ số context.render_context với self. Hàm ý về điều đó phải mà self được sử dụng để xác định các trường hợp theo một trong hai cách sau:

  1. self tài liệu tham khảo một ví dụ cụ thể của lớp trong toàn bộ hệ thống tài liệu tham khảo
  2. self rằng lớp mà thôi, và theo thứ tự để tham chiếu ví dụ, ngữ cảnh hiển thị là bắt buộc

Nếu 1 là đúng, tại sao không chỉ liên kết dữ liệu với self?

Nếu 2 là đúng và ngữ cảnh hiển thị "được liên kết với ngữ cảnh của mẫu hiện đang được hiển thị", làm cách nào để phân biệt giữa hai mẫu của thẻ mẫu trên cùng một trang?

Node có được kích hoạt riêng rẽ mỗi khi thẻ được gọi không? Nếu vậy, tại sao các vấn đề đồng thời? Nếu không, tai sao không?

Trả lời

0

Nhận thông tin chi tiết hơn với số đọc this.

Mẫu được biên dịch khi được tải. Bất kỳ đối số nào được chuyển vào hàm thẻ đều là 'tĩnh'. Chúng là các chuỗi ký tự, hoặc chúng là các chuỗi được sử dụng như các định danh để tra cứu các biến bị ràng buộc trong ngữ cảnh hiển thị.

Do đó đối tượng Nút được khởi tạo cho mỗi thẻ và treo xung quanh sẵn sàng để sử dụng bất cứ khi nào mẫu được sử dụng (và tự nhiên mẫu có thể được sử dụng trong bất kỳ số lượng chuỗi nào).

Do đó, self trong câu hỏi của tôi là danh tính của Nút cụ thể trong mẫu. Kết hợp với bối cảnh render, điều này mang lại một bản sắc duy nhất để treo các biến mẫu.