Login

Selectively change fields, widgets or labels in forms created from models

Author:
danjak
Posted:
February 28, 2007
Language:
Python
Version:
Pre .96
Score:
4 (after 4 ratings)

Allows you to override form fields created by form_for_model or form_for_instance, without having to redefine whole fields for example in form.base_fields.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def form_decorator(fields = {}, attrs = {}, widgets = {}, 
    labels = {}, choices = {}):
    
    """
    This function helps to add overrides when creating forms from models/instances.
    Pass in dictionary of fields to override certain fields altogether, otherwise
    add widgets or labels as desired.
    
    For example:
    
    class Project(models.Model):
    
        name = models.CharField(maxlength = 100)
        description = models.TextField()
        owner = models.ForeignKey(User)
   
    project_fields = dict(
        owner = None
    )
    
    project_widgets = dict(
        name = forms.TextInput({"size":40}),
        description = forms.Textarea({"rows":5, "cols":40}))
    
    project_labels = dict(
        name = "Enter your project name here"
    )
    
    callback = form_decorator(project_fields, project_widgets, project_labels)
    project_form = forms.form_for_model(Project, formfield_callback = callback)
    
    This saves having to redefine whole fields for example just to change a widget
    setting or label.
    """
    
    def formfields_callback(f, **kw):
    
        if f.name in fields:
            
            # replace field altogether
            field = fields[f.name]
            f.initial = kw.pop("initial", None)
            return field
        
        if f.name in widgets:
            
            kw["widget"] = widgets[f.name]

        if f.name in attrs:
            
            widget = kw.pop("widget", f.formfield().widget)
            if widget :
                widget.attrs.update(attrs[f.name])
                kw["widget"] = widget

        if f.name in labels:
        
            kw["label"] = labels[f.name]
        
        if f.name in choices:
        
            choice_set = choices[f.name]
            if callable(choice_set) : choice_set = choice_set()
            kw["choices"] = choice_set
            
                
        return f.formfield(**kw)
    
    return formfields_callback

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.