2010-09-09 111 views
9

我想为我的表单中的所有字段设置TextInput Widget的类属性为一个值,而不必在Meta中列出它们:widgets = {....这可能吗?如何为Django ModelForm设置默认控件属性?

谢谢。在所有的领域

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

在您的形式使用新的部件:

回答

13

您可以覆盖的构造,以修改所有的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 

可以吗用装饰器覆盖init?另外,在attrs.update()之前应该有一个if语句,因为我想设置一个默认值,而不是覆盖可能已经存在的值。 - 凯文

未经测试,但我想你可以继承自MyForm,如果你使用这很多。

+0

你可以用装饰器重写init吗?另外,在attrs.update()之前应该有一个if语句,因为我想设置一个默认值,而不是覆盖可能已经存在的值。 – Kevin 2010-09-27 21:44:20

+0

我认为装饰器是用于可调用的,覆盖构造函数应该通过正常的继承机制来完成。在Django中,有一些函数返回类并不罕见,这些函数通常被称为“工厂”。更新为“if”条件(未经测试)。 – 2010-09-28 15:02:40

3

与CSS类创建一个新的widget

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

这感觉更Djangonic的方式来完成任务,但它并不完全看起来像什么凯文是我后... – codekoala 2010-09-24 14:43:19

4

一件事,我已经在过去做的是创造返回领域的lambda函数我经常使用:

from django import forms 

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

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

我不记得到底为什么我选择使用一个函数T Ø处理我的情况,但我怀疑它有一些东西需要与创建forms.TextInput对象每个表单字段的不同实例....

+0

这是我现在要做的。有必要创建单独的forms.Select实例。 – Kevin 2010-09-26 23:59:33

1

您可以使用下面:

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

现在,每次你想为某个小部件使用默认attrs时,你只需要创建继承自DefaultAttrForm或DefaultAttrModelForm的类并覆盖方法get_default_attrs。例如,对于普通的Django形式:

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'} 

对于型号形式使用下列内容:

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

对于ModelForm,我们可以使用它。

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