Ticket #9223: 9223.diff
File 9223.diff, 5.8 KB (added by , 16 years ago) |
---|
-
django/forms/models.py
123 123 data[f.name] = f.value_from_object(instance) 124 124 return data 125 125 126 def fields_for_model(model, fields=None, exclude=None, formfield_callback=lambda f: f.formfield()):126 def fields_for_model(model, fields=None, exclude=None, widgets=None, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)): 127 127 """ 128 128 Returns a ``SortedDict`` containing form fields for the given model. 129 129 … … 137 137 # TODO: if fields is provided, it would be nice to return fields in that order 138 138 field_list = [] 139 139 opts = model._meta 140 kwargs = {} 140 141 for f in opts.fields + opts.many_to_many: 141 142 if not f.editable: 142 143 continue … … 144 145 continue 145 146 if exclude and f.name in exclude: 146 147 continue 147 formfield = formfield_callback(f) 148 if widgets and f.name in widgets: 149 kwargs['widget'] = widgets[f.name] 150 formfield = formfield_callback(f, **kwargs) 148 151 if formfield: 149 152 field_list.append((f.name, formfield)) 150 153 return SortedDict(field_list) … … 154 157 self.model = getattr(options, 'model', None) 155 158 self.fields = getattr(options, 'fields', None) 156 159 self.exclude = getattr(options, 'exclude', None) 160 self.widgets = getattr(options, 'widgets', None) 157 161 158 162 159 163 class ModelFormMetaclass(type): 160 164 def __new__(cls, name, bases, attrs): 161 165 formfield_callback = attrs.pop('formfield_callback', 162 lambda f : f.formfield())166 lambda f, **kwargs: f.formfield(**kwargs)) 163 167 try: 164 168 parents = [b for b in bases if issubclass(b, ModelForm)] 165 169 except NameError: … … 177 181 if opts.model: 178 182 # If a model is defined, extract form fields from it. 179 183 fields = fields_for_model(opts.model, opts.fields, 180 opts.exclude, formfield_callback)184 opts.exclude, opts.widgets, formfield_callback) 181 185 # Override default model fields with any custom declared ones 182 186 # (plus, include all the other declared fields). 183 187 fields.update(declared_fields) -
tests/modeltests/model_forms/models.py
220 220 >>> CategoryForm.base_fields.keys() 221 221 ['name'] 222 222 223 Using 'widgets' 224 225 >>> class CategoryForm(ModelForm): 226 ... 227 ... class Meta: 228 ... model = Category 229 ... fields = ['name', 'url'] 230 ... widgets = { 231 ... 'name': forms.Textarea, 232 ... 'url': forms.TextInput(attrs={'class': 'url'}) 233 ... } 234 235 >>> str(CategoryForm()['name']) 236 '<textarea id="id_name" rows="10" cols="40" name="name"></textarea>' 237 238 >>> str(CategoryForm()['url']) 239 '<input id="id_url" type="text" class="url" name="url" maxlength="40" />' 240 223 241 Don't allow more than one 'model' definition in the inheritance hierarchy. 224 242 Technically, it would generate a valid form, but the fact that the resulting 225 243 save method won't deal with multiple objects is likely to trip up people not -
docs/topics/forms/modelforms.txt
305 305 306 306 .. _section on saving forms: `The save() method`_ 307 307 308 Overriding the default field types 309 ---------------------------------- 308 Overriding the default field types or widgets 309 --------------------------------------------- 310 310 311 311 The default field types, as described in the `Field types`_ table above, are 312 312 sensible defaults. If you have a ``DateField`` in your model, chances are you'd 313 313 want that to be represented as a ``DateField`` in your form. But 314 ``ModelForm`` gives you the flexibility of changing the form field type 315 for a given model field. You do this by declaratively specifying fields like 316 you would in a regular ``Form``. Declared fields will override the default 317 ones generated by using the ``model`` attribute. 314 ``ModelForm`` gives you the flexibility of changing the form field type and 315 widget for a given model field. 318 316 317 To specify a custom widget for a field use the ``widgets`` attribute og the 318 inner ``Meta`` class. For example if you want the default textarea for the TextField 319 to have custom ``cols`` and ``rows`` attributes you can override its widget: 320 321 >>> class ArticleForm(ModelForm) 322 ... class Meta: 323 ... model = ArticleForm 324 ... fields = ['title', 'text'] 325 ... widgets = { 326 ... 'text': Textarea(attrs={'cols': 80, 'rows': 20}) 327 ... } 328 329 ``Widgets`` dictionary accepts both widget instances (i.e. ``Textarea(...)``) as well 330 as classes (i.e. ``Textarea``). 331 332 If you want to further customize the field including its type, label etc., you do this 333 by declaratively specifying fields like you would in a regular ``Form``. Declared 334 fields will override the default ones generated by using the ``model`` attribute. 335 319 336 For example, if you wanted to use ``MyDateFormField`` for the ``pub_date`` 320 337 field, you could do the following:: 321 338 … … 325 342 ... class Meta: 326 343 ... model = Article 327 344 328 If you want to override a field's default widget, then specify the ``widget``345 If you want to override a field's default label, then specify the ``label`` 329 346 parameter when declaring the form field:: 330 347 331 348 >>> class ArticleForm(ModelForm): 332 ... pub_date = DateField( widget=MyDateWidget())349 ... pub_date = DateField(label='Publication date') 333 350 ... 334 351 ... class Meta: 335 352 ... model = Article