2010-09-09 4 views

Antwort

13

Sie den Konstruktor, um außer Kraft setzen können alle TextInput- Widgets zu ändern:

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 

können Sie Override Init mit einem Dekorator? Außerdem sollte es eine if-Anweisung vor der attrs.update() geben, weil ich einen Standardwert festlegen und nicht überschreiben möchte, was schon da ist. - Kevin

Nicht getestet, aber ich denke, Sie können einfach von MyForm erben, wenn Sie dies häufig verwenden.

+0

können Sie init mit einem Dekorator überschreiben? Außerdem sollte es eine if-Anweisung vor der attrs.update() geben, weil ich einen Standardwert festlegen und nicht überschreiben möchte, was schon da ist. – Kevin

+0

Ich denke, Dekoratoren sollen mit callables verwendet werden, das Überschreiben des Konstruktors sollte über den normalen Vererbungsmechanismus erfolgen. Im Django ist es nicht ungewöhnlich, dass einige Funktionen Klassen zurückgeben, diese Funktionen werden normalerweise 'Fabriken' genannt. Aktualisiert mit "if" Bedingung (ungetestet). –

3

Erstellen Sie ein neues Widget mit Ihrem CSS-Klasse:

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

Sie in Ihrem Formular verwenden Sie Ihr neues Widget in allen Bereichen:

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

Das fühlt sich an wie der mehr Djangonic Weg, um die Aufgabe zu erfüllen, aber es scheint nicht ganz wie das, was nach mir Kevin ist ... – codekoala

4

Eine Sache, die ich in der Vergangenheit getan haben, ist erstellen eine Lambda-Funktion, die die Felder zurück benutze ich oft:

from django import forms 

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

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

ich erinnere mich nicht, warum genau ich eine Funktion t zu verwenden, entschieden o Griff meine Situation, aber ich vermute, dass es etwas mit dem Erstellen separate Instanzen des forms.TextInput Objekt für jedes Formularfeld ....

+0

Das ist, was ich jetzt tun. Es ist erforderlich, separate Instanzen von Formularen zu erstellen. – Kevin

1

Sie folgende verwenden können, zu tun hatte:

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

Jetzt, Jedes Mal, wenn Sie für ein Widget Standardattribute verwenden möchten, müssen Sie nur eine Klasse erstellen, die von DefaultAttrForm oder DefaultAttrModelForm erbt und die Methode get_default_attrs überschreibt. Django Formular Beispiel für normal:

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

Für Modell Form Gebrauch folgende:

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

Für ModelForm können wir dies verwenden.

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 
Verwandte Themen