2009-11-27 36 views
37

Tôi đang lặp qua các trường của biểu mẫu và cho một số trường nhất định, tôi muốn bố cục hơi khác, yêu cầu HTML thay đổi.Nhận loại phụ tùng biểu mẫu Django từ trong mẫu

Để làm điều này một cách chính xác, tôi chỉ cần biết loại tiện ích con. Tên lớp của nó hoặc một cái gì đó tương tự. Trong python chuẩn, điều này rất dễ dàng! field.field.widget.__class__.__name__

Thật không may, bạn không được phép truy cập vào các biến gạch dưới trong mẫu. Tuyệt vời!

Bạn thể kiểm tra field.field.widget.input_type nhưng điều này chỉ làm việc cho văn bản/mật khẩu <input ../> loại. Tôi cần độ phân giải cao hơn thế.

Đối với tôi, tuy nhiên rất khó nhìn, điều này có ý nghĩa nhất khi thực hiện việc này ở cấp mẫu. Tôi đã thuê ngoài mã bit xử lý HTML cho các trường cho một mẫu riêng biệt được đưa vào vòng lặp trường. Điều này có nghĩa là nó nhất quán trên ModelForm s và tiêu chuẩn Form s (điều gì đó sẽ không đúng nếu tôi đã viết một lớp Mẫu trung gian).

Nếu bạn có thể thấy cách tiếp cận toàn cầu không yêu cầu tôi chỉnh sửa biểu mẫu 20 lẻ, hãy cho tôi biết!

+0

Báo cáo lỗi có liên quan hoặc yêu cầu tính năng: https://code.djangoproject.com/ticket/13009 – Flimm

Trả lời

4

Tính đến Django 1.11, bạn có thể chỉ cần sử dụng widget.input_type. Ví dụ:

{% for field in form.visible_fields %} 
    <input type="{{ field.field.widget.input_type }}" 
      id="{{ field.id_for_label }}" 
      name="{{ field.html_name }}" 
      placeholder="{{ field.label }}" 
      maxlength="{{ field.field.max_length }}" /> 
{% endfor %} 
40

Tạo thẻ mẫu có thể hoạt động? Một cái gì đó như field.field.widget|widget_type

Chỉnh sửa từ Oli: Điểm tốt! Tôi vừa viết một bộ lọc:

from django import template 
register = template.Library() 

@register.filter('klass') 
def klass(ob): 
    return ob.__class__.__name__ 

Và bây giờ {{ object|klass }} hiển thị chính xác. Bây giờ tôi đã tìm ra cách sử dụng nó bên trong câu lệnh if của mẫu.

Chỉnh sửa từ Oli # 2: Tôi cần sử dụng kết quả của điều đó trong một statetement trong mẫu, vì vậy tôi chỉ chuyển tất cả logic đó vào templatetag. Ma thuật. Cảm ơn đã chọc tôi đi đúng hướng.

+0

Chào mừng bạn đến với SO btw. – Oli

+1

Cảm ơn giải pháp này. Về Chỉnh sửa # 2 - với 'if tags' nâng cao trong Django 1.2, bạn có thể thực hiện các so sánh loại tiện ích này ngay trong mẫu. Tôi đã đăng một ví dụ như một câu trả lời riêng biệt. – zlovelady

+1

Một bộ lọc đẹp khác để thêm (nếu không phải người Python sẽ xử lý các mẫu của bạn) giống như thế này, cho các trường hợp được sử dụng nhiều nhất: 'def is_checkboxes (form_field_obj): return (form_field_obj .__ class __.__ name__ ==" CheckboxSelectMultiple ")' ... thì bạn có thể thực hiện '{% if field | is_checkboxes%}' và mọi người sẽ không phát hiện ra (... không trả về) – hangtwenty

33

Theo dõi câu trả lời được chấp nhận - nâng cao if tag trong Django 1.2 cho phép bạn sử dụng bộ lọc trong các so sánh if tag. Vì vậy, bây giờ bạn có thể làm tùy chỉnh html của bạn/logic trong các mẫu như sau:

<ul> 
{% for field in form.fields %} 
    <li> 
    {% if field.field.widget|klass == "Textarea" %} 
    <!-- do something special for Textarea --> 
    <h2>Text Areas are Special </h2> 
    {% else %}  
     {{ field.errors }} 
     {{ field.label_tag }} 
     {{ field }} 
    {% endif %} 

    </li> 
{% endfor %} 
</ul> 
+3

+1 để theo dõi – Oli

+0

Mục đích của * field.field.widget *, thay vì chỉ sử dụng * field.widget * là gì? – Wipqozn

+0

@Wipqozn trong kinh nghiệm của tôi 'field.widget' thường tạo ra không có gì - tôi không chắc chắn về điều này, nhưng có lẽ nó chỉ được thiết lập nếu bạn đặt nó bằng tay. 'field.field.widget' hoạt động. – hangtwenty

16

Tiếp theo câu trả lời từ Oli và rinti: Tôi sử dụng cái này và tôi nghĩ rằng đó là đơn giản hơn một chút: Mã

mẫu : mã {{ field|fieldtype }}

lọc:

from django import template 
register = template.Library() 

@register.filter('fieldtype') 
def fieldtype(field): 
    return field.field.widget.__class__.__name__ 
Các vấn đề liên quan