2011-12-28 32 views
17

Tôi có đoạn code sau trong template của tôiDjango Template - tăng giá trị của một biến

{% set counter = 0 %} 
{% for object in object_list %} 
    {% if object.attr1 == list1.attr1 and object.attr2 = list2.attr2 %} 
     <li><a href="{{ object.get_absolute_url }}"> Link {{counter++}} </a></li> 
    {% endif %} 
{% endfor %} 

tôi thiết lập các giá trị của một biến sử dụng custom tag này và những gì tôi muốn làm là để tăng giá trị chỉ khi vòng lặp if được thỏa mãn. Tôi biết {{counter++}} không hoạt động. Nhưng làm thế nào tôi có thể viết một thẻ tùy chỉnh mà sẽ làm nhiệm vụ tương tự?

Trả lời

24

Thay đổi trạng thái của đối tượng trong mẫu Django không được khuyến khích. Bạn có lẽ nên cắn viên đạn, tính toán điều kiện trước và chuyển trạng thái thừa vào mẫu để bạn có thể đơn giản hóa logic mẫu.

Tôi không thuần khiết trong vấn đề này bằng cách này, nhưng tôi đã bị cắn bởi những hạn chế có chủ đích của các mẫu Django một vài lần. Bạn tốt hơn không chiến đấu chống lại nó, theo ý kiến ​​của tôi.

Do ý định của bạn dường như là lọc ra các mục không phù hợp, một giải pháp thay thế là lọc ra các mục đó trong chế độ xem và sau đó sử dụng {{ forloop.counter }} để sắp xếp văn bản liên kết bạn muốn. Vì vậy, trong giao diện bạn có một cái gì đó như thế này:

new_lst = filter(lambda x: x.attr0 == attr0 and x.attr1 == attr1, lst) 

Và sau đó, trong mẫu của bạn:

{% for object in new_lst %} 
    <li><a href="{{ object.get_absolute_url }}"> Link {{ forloop.counter }} </a></li> 
{% endfor %} 
+1

1 đẹp câu trả lời, [để tham khảo] (https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for) , tha thứ cho sự trừng phạt –

+0

Tôi thường không cố gắng để vượt qua những hạn chế của Django nhưng lần này tôi thực sự cần thiết để làm điều đó .... Trong điều kiện của tôi '{{forloop.counter}}' không giúp đỡ. Tuy nhiên tôi đã đưa ra mã mẫu của tôi, bạn có thể cho biết nếu tôi có thể sử dụng '{{forloop.counter}}' – Sachin

+0

+1 Sử dụng bộ đếm forloop là cách để đi đến đây. @Sachin: nếu bạn muốn sử dụng không dựa trên '{{forloop.counter0}}', mặc dù. –

0

Tôi vừa phát hiện ra câu trả lời bản thân mình. Như tôi đã nói tôi đã sử dụng this custom tag, gán giá trị cho một biến. Những gì thực sự là thiết lập cho một giá trị cho một biến trong context vì vậy tôi chỉ lấy giá trị từ ngữ cảnh và tăng nó.

Đây là mã

class IncrementVarNode(template.Node): 

    def __init__(self, var_name): 
     self.var_name = var_name 

    def render(self,context): 
     value = context[self.var_name] 
     context[self.var_name] = value + 1 
     return u"" 

def increment_var(parser, token): 

    parts = token.split_contents() 
    if len(parts) < 2: 
     raise template.TemplateSyntaxError("'increment' tag must be of the form: {% increment <var_name> %}") 
    return IncrementVarNode(parts[1]) 

register.tag('increment', increment_var) 

Nó có thể được sử dụng như thế này {% increment <var_name> %} nhưng var_name này lẽ ra phải được thiết lập để một giá trị trước đó bằng cách sử dụng thẻ tùy chỉnh nêu trên như {% set <var_name> = <var_value> %}

+0

Tôi nhận được một số hành vi kỳ lạ với điều này.cập nhật của tôi không lưu trong một vòng lặp nhúng cho, như thể một không gian tên phụ đang được sao chép tạm thời, sau đó bị xóa khi vòng lặp for đã biến mất, bất kỳ ý tưởng nào? – Jeremy

10

Mặc dù điều này đã được trả lời và đi ngược lại những gì đã được nói rằng tôi chỉ có một suy nghĩ và không thể thấy quá nhiều tổn hại nếu có lẽ bạn đã thực hiện lớp truy cập đơn giản như

class Counter: 
    count = 0 

    def increment(self): 
     self.count += 1 
     return '' 

    def decrement(self): 
     self.count -= 1 
     return '' 

    def double(self): 
     self.count *= 2 
     return '' 

sau đó trong mẫu của bạn {{ counter.increment }}{{ counter.count }}, vv

+1

Nhưng làm thế nào tôi sẽ liên kết điều này với nút Mẫu? – Sachin

+0

nó không có nghĩa là làm việc như một thẻ chỉ được thông qua như là một phần của bối cảnh –

+0

Oh! giải pháp mà tôi đã có Tôi muốn có một cái gì đó liên quan đến mẫu – Sachin

Các vấn đề liên quan