2010-09-09 24 views

Trả lời

13

Bạn có thể ghi đè lên các nhà xây dựng để sửa đổi tất cả các widget TextInput:

from django import forms 

class MyForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     for name, field in self.fields.items(): 
      if field.widget.__class__ == forms.widgets.TextInput: 
       if 'class' in field.widget.attrs: 
        field.widget.attrs['class'] += ' my-class' 
       else: 
        field.widget.attrs.update({'class':'my-class'}) 
    class Meta: 
     model = MyModel 

thể bạn ghi đè init với một người trang trí? cũng có, nên có một tuyên bố nếu trước attrs.update() bởi vì tôi muốn thiết lập một mặc định hơn là ghi đè lên những gì có thể đã có. - Kevin

Chưa được kiểm tra, nhưng tôi đoán bạn có thể kế thừa từ MyForm nếu bạn sử dụng quá nhiều.

+0

bạn có thể ghi đè init bằng trình trang trí không? cũng có, nên có một tuyên bố nếu trước attrs.update() bởi vì tôi muốn thiết lập một mặc định hơn là ghi đè lên những gì có thể đã có. – Kevin

+0

Tôi nghĩ rằng trang trí được dự định sẽ được sử dụng với callables, trọng các nhà xây dựng nên được thực hiện thông qua cơ chế thừa kế bình thường. Trong django nó không phải là không phổ biến để có một số chức năng trở về lớp học, các chức năng này thường được gọi là 'nhà máy'. Cập nhật với điều kiện "if" (chưa được kiểm tra). –

3

Tạo một widget mới với lớp CSS của bạn:

class PrettyWidget(forms.TextInput): 
    class Media: 
     css = { 
      'all': ('pretty.css',) 
     } 

Trong biểu mẫu sử dụng phụ tùng mới của bạn trong tất cả các lĩnh vực của bạn:

class ContactForm(forms.Form): 
    subject = TextField(widget=PrettyWidget) 
+2

Điều này cảm thấy giống như cách Djangonic để hoàn thành nhiệm vụ, nhưng nó không hoàn toàn giống như những gì Kevin đang theo sau tôi ... – codekoala

4

Một điều tôi đã làm trong quá khứ là tạo hàm lambda trả về các trường tôi thường sử dụng:

from django import forms 

fancy = lambda: forms.TextInput(attrs={'class': 'derp'}) 

class MyForm(forms.Form): 
    attr1 = fancy() 
    attr2 = fancy() 
    attr3 = fancy() 

Tôi không nhớ tại sao chính xác tôi đã chọn sử dụng hàm o xử lý tình huống của tôi, nhưng tôi nghi ngờ rằng nó có cái gì để làm với việc tạo ra các trường hợp riêng biệt của đối tượng forms.TextInput cho từng lĩnh vực hình thức ....

+0

Đây là những gì tôi làm bây giờ. Nó là cần thiết để tạo ra các trường hợp riêng biệt của các hình thức. – Kevin

1

Bạn có thể sử dụng như sau:

def set_attrs_for_fields(fields, default_attrs): 
    for field_name in fields: 
     field = fields[field_name] 

     try: 
      default_widget_attr = default_attrs[field.widget.__class__] 
      field.widget.attrs = default_widget_attr 
     except KeyError: 
      pass 


class DefaultAttrForm(forms.Form): 

    def __init__(self, *args, **kwargs): 

     super(DefaultAttrForm, self).__init__(*args, **kwargs) 

     set_attrs_for_fields(self.fields, self.get_default_attrs()) 


    def get_default_attrs(self): 
     ''' 
     Child class should overwrite this method and return dict with example format 

     {forms.TextInput: {'class': 'my_value'}} 

     where keys, are widget classes for which default attrs will be set. 
     ''' 
     raise NotImplementedError() 


class DefaultAttrModelForm(ModelForm): 

    def __init__(self, *args, **kwargs): 

     super(DefaultAttrModelForm, self).__init__(*args, **kwargs) 

     set_attrs_for_fields(self.fields, self.get_default_attrs()) 


    def get_default_attrs(self): 
     ''' 
     Child class should overwrite this method and return dict with example format 

     {forms.TextInput: {'class': 'my_value'}} 

     where keys, are widget classes for which default attrs will be set. 
     ''' 
     raise NotImplementedError() 

Bây giờ, mỗi khi bạn muốn sử dụng attrs mặc định cho một số widget, bạn chỉ cần tạo class thừa hưởng từ DefaultAttrForm hoặc DefaultAttrModelForm và overwrite method get_default_attrs. Ví dụ cho mẫu Django bình thường:

class MyForm(DefaultAttrForm): 
    my_field1 = forms.CharField(widget=forms.TextInput()) 
    my_field2 = forms.CharField(widget=forms.PasswordInput(attrs={'my_non_default': 'Non default'})) 

    def get_default_attrs(self): 
     # all fields with widget TextInput will have 
     # default attrs set to {'class': 'my_value'} 

     return {forms.TextInput: {'class': 'my_value'}, 
       } 


In [1]: form = MyForm() 

In [2]: form.fields['my_field1'].widget.attrs 
Out[2]: {'class': 'my_value'} 

In [3]: form.fields['my_field2'].widget.attrs 
Out[3]: {'my_non_default': 'Non default'} 

Đối với mẫu hình thức sử dụng như sau:

class MyModelForm(DefaultAttrModelForm): 

    class Meta: 
     model = my_model 

    def get_default_attrs(self): 
     # all fields with widget TextInput will have 
     # default attrs set to {'class': 'my_value'} 

     return {forms.TextInput: {'class': 'my_value'}, 
       } 


In [1]: form = MyModelForm() 

In [2]: form.fields['my_field1'].widget.attrs 
Out[2]: {'class': 'my_value'} 

In [3]: form.fields['my_field2'].widget.attrs 
Out[3]: {'my_non_default': 'Non default'} 
0

Đối với ModelForm, chúng tôi có thể sử dụng tính năng này.

from django import forms 
from django.contrib.auth.models import User 

class UserForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(UserForm, self).__init__(*args, **kwargs) 

     # change a widget attribute: 
     self.fields['user_permissions'].widget.attrs["size"] = 5 
     self.fields['user_permissions'].widget.attrs["class"] = 'form-control required' 

    class Meta: 
     model = User 
Các vấn đề liên quan