Ticket #6042: modelforms.diff
File modelforms.diff, 81.2 KB (added by , 17 years ago) |
---|
-
django/newforms/models.py
diff --git a/django/newforms/models.py b/django/newforms/models.py index 51ed16f..77b2b32 100644
a b and database field objects. 6 6 from django.utils.translation import ugettext_lazy as _ 7 7 from django.utils.encoding import smart_unicode 8 8 from django.utils.datastructures import SortedDict 9 from django.core.exceptions import ImproperlyConfigured 9 10 10 from util import ValidationError 11 from util import ValidationError, ErrorList 11 12 from forms import BaseForm 12 13 from fields import Field, ChoiceField, EMPTY_VALUES 13 14 from widgets import Select, SelectMultiple, MultipleHiddenInput 14 15 15 16 __all__ = ( 17 'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model', 16 18 'save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields', 17 19 'ModelChoiceField', 'ModelMultipleChoiceField' 18 20 ) … … def form_for_fields(field_list): 132 134 for f in field_list if f.editable]) 133 135 return type('FormForFields', (BaseForm,), {'base_fields': fields}) 134 136 137 138 # ModelForms ################################################################# 139 140 def model_to_dict(instance, fields=None, exclude=None): 141 """ 142 Returns a dict containing the data in ``instance`` suitable for passing as 143 a Form's ``initial`` keyword argument. 144 145 ``fields`` is an optional list of field names. If provided, only the named 146 fields will be included in the returned dict. 147 148 ``exclude`` is an optional list of field names. If provided, the named 149 fields will be excluded from the returned dict, even if they are listed in 150 the ``fields`` argument. 151 """ 152 # avoid a circular import 153 from django.db.models.fields.related import ManyToManyField 154 opts = instance._meta 155 data = {} 156 for f in opts.fields + opts.many_to_many: 157 if not f.editable: 158 continue 159 if fields and not f.name in fields: 160 continue 161 if exclude and f.name in exclude: 162 continue 163 if isinstance(f, ManyToManyField): 164 # If the object doesn't have a primry key yet, just use an empty 165 # list for its m2m fields. Calling f.value_from_object will raise 166 # an exception. 167 if instance.pk is None: 168 data[f.name] = [] 169 else: 170 # MultipleChoiceWidget needs a list of pks, not object instances. 171 data[f.name] = [obj.pk for obj in f.value_from_object(instance)] 172 else: 173 data[f.name] = f.value_from_object(instance) 174 return data 175 176 def fields_for_model(model, fields=None, exclude=None, formfield_callback=lambda f: f.formfield()): 177 """ 178 Returns a ``SortedDict`` containing form fields for the given model. 179 180 ``fields`` is an optional list of field names. If provided, only the named 181 fields will be included in the returned fields. 182 183 ``exclude`` is an optional list of field names. If provided, the named 184 fields will be excluded from the returned fields, even if they are listed 185 in the ``fields`` argument. 186 """ 187 # TODO: if fields is provided, it would be nice to return fields in that order 188 field_list = [] 189 opts = model._meta 190 for f in opts.fields + opts.many_to_many: 191 if not f.editable: 192 continue 193 if fields and not f.name in fields: 194 continue 195 if exclude and f.name in exclude: 196 continue 197 formfield = formfield_callback(f) 198 if formfield: 199 field_list.append((f.name, formfield)) 200 return SortedDict(field_list) 201 202 class ModelFormOptions(object): 203 def __init__(self, options=None): 204 self.model = getattr(options, 'model', None) 205 self.fields = getattr(options, 'fields', None) 206 self.exclude = getattr(options, 'exclude', None) 207 208 class ModelFormMetaclass(type): 209 def __new__(cls, name, bases, attrs): 210 # TODO: no way to specify formfield_callback yet, do we need one, or 211 # should it be a special case for the admin? 212 fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] 213 fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) 214 215 # If this class is subclassing another Form, add that Form's fields. 216 # Note that we loop over the bases in *reverse*. This is necessary in 217 # order to preserve the correct order of fields. 218 for base in bases[::-1]: 219 if hasattr(base, 'base_fields'): 220 fields = base.base_fields.items() + fields 221 declared_fields = SortedDict(fields) 222 223 opts = ModelFormOptions(attrs.get('Meta', None)) 224 attrs['_meta'] = opts 225 226 # Don't allow more than one Meta model defenition in bases. The fields 227 # would be generated correctly, but the save method won't deal with 228 # more than one object. 229 base_models = [] 230 for base in bases: 231 base_opts = getattr(base, '_meta', None) 232 base_model = getattr(base_opts, 'model', None) 233 if base_model is not None: 234 base_models.append(base_model) 235 if len(base_models) > 1: 236 raise ImproperlyConfigured("%s's base classes define more than one model." % name) 237 238 # If a model is defined, extract form fields from it and add them to base_fields 239 if attrs['_meta'].model is not None: 240 # Don't allow a subclass to define a Meta model if a parent class has. 241 # Technically the right fields would be generated, but the save 242 # method will not deal with more than one model. 243 for base in bases: 244 base_opts = getattr(base, '_meta', None) 245 base_model = getattr(base_opts, 'model', None) 246 if base_model is not None: 247 raise ImproperlyConfigured('%s defines more than one model.' % name) 248 model_fields = fields_for_model(opts.model, opts.fields, opts.exclude) 249 # fields declared in base classes override fields from the model 250 model_fields.update(declared_fields) 251 attrs['base_fields'] = model_fields 252 else: 253 attrs['base_fields'] = declared_fields 254 return type.__new__(cls, name, bases, attrs) 255 256 class BaseModelForm(BaseForm): 257 def __init__(self, instance, data=None, files=None, auto_id='id_%s', prefix=None, 258 initial=None, error_class=ErrorList, label_suffix=':'): 259 self.instance = instance 260 opts = self._meta 261 object_data = model_to_dict(instance, opts.fields, opts.exclude) 262 # if initial was provided, it should override the values from instance 263 if initial is not None: 264 object_data.update(initial) 265 BaseForm.__init__(self, data, files, auto_id, prefix, object_data, error_class, label_suffix) 266 267 def save(self, commit=True): 268 """ 269 Saves this ``form``'s cleaned_data into model instance ``self.instance``. 270 271 If commit=True, then the changes to ``instance`` will be saved to the 272 database. Returns ``instance``. 273 """ 274 if self.instance.pk is None: 275 fail_message = 'created' 276 else: 277 fail_message = 'changed' 278 return save_instance(self, self.instance, self._meta.fields, fail_message, commit) 279 280 class ModelForm(BaseModelForm): 281 __metaclass__ = ModelFormMetaclass 282 283 284 # Fields ##################################################################### 285 135 286 class QuerySetIterator(object): 136 287 def __init__(self, queryset, empty_label, cache_choices): 137 288 self.queryset = queryset … … class QuerySetIterator(object): 142 293 if self.empty_label is not None: 143 294 yield (u"", self.empty_label) 144 295 for obj in self.queryset: 145 yield (obj. _get_pk_val(), smart_unicode(obj))296 yield (obj.pk, smart_unicode(obj)) 146 297 # Clear the QuerySet cache if required. 147 298 if not self.cache_choices: 148 299 self.queryset._result_cache = None -
new file docs/form_for_model.txt
diff --git a/docs/form_for_model.txt b/docs/form_for_model.txt new file mode 100644 index 0000000..6761c15
- + 1 Generating forms for models 2 =========================== 3 4 If you're building a database-driven app, chances are you'll have forms that 5 map closely to Django models. For instance, you might have a ``BlogComment`` 6 model, and you want to create a form that lets people submit comments. In this 7 case, it would be redundant to define the field types in your form, because 8 you've already defined the fields in your model. 9 10 For this reason, Django provides a few helper functions that let you create a 11 ``Form`` class from a Django model. 12 13 ``form_for_model()`` 14 -------------------- 15 16 The method ``django.newforms.form_for_model()`` creates a form based on the 17 definition of a specific model. Pass it the model class, and it will return a 18 ``Form`` class that contains a form field for each model field. 19 20 For example:: 21 22 >>> from django.newforms import form_for_model 23 24 # Create the form class. 25 >>> ArticleForm = form_for_model(Article) 26 27 # Create an empty form instance. 28 >>> f = ArticleForm() 29 30 It bears repeating that ``form_for_model()`` takes the model *class*, not a 31 model instance, and it returns a ``Form`` *class*, not a ``Form`` instance. 32 33 Field types 34 ~~~~~~~~~~~ 35 36 The generated ``Form`` class will have a form field for every model field. Each 37 model field has a corresponding default form field. For example, a 38 ``CharField`` on a model is represented as a ``CharField`` on a form. A 39 model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is 40 the full list of conversions: 41 42 =============================== ======================================== 43 Model field Form field 44 =============================== ======================================== 45 ``AutoField`` Not represented in the form 46 ``BooleanField`` ``BooleanField`` 47 ``CharField`` ``CharField`` with ``max_length`` set to 48 the model field's ``max_length`` 49 ``CommaSeparatedIntegerField`` ``CharField`` 50 ``DateField`` ``DateField`` 51 ``DateTimeField`` ``DateTimeField`` 52 ``DecimalField`` ``DecimalField`` 53 ``EmailField`` ``EmailField`` 54 ``FileField`` ``FileField`` 55 ``FilePathField`` ``CharField`` 56 ``FloatField`` ``FloatField`` 57 ``ForeignKey`` ``ModelChoiceField`` (see below) 58 ``ImageField`` ``ImageField`` 59 ``IntegerField`` ``IntegerField`` 60 ``IPAddressField`` ``IPAddressField`` 61 ``ManyToManyField`` ``ModelMultipleChoiceField`` (see 62 below) 63 ``NullBooleanField`` ``CharField`` 64 ``PhoneNumberField`` ``USPhoneNumberField`` 65 (from ``django.contrib.localflavor.us``) 66 ``PositiveIntegerField`` ``IntegerField`` 67 ``PositiveSmallIntegerField`` ``IntegerField`` 68 ``SlugField`` ``CharField`` 69 ``SmallIntegerField`` ``IntegerField`` 70 ``TextField`` ``CharField`` with ``widget=Textarea`` 71 ``TimeField`` ``TimeField`` 72 ``URLField`` ``URLField`` with ``verify_exists`` set 73 to the model field's ``verify_exists`` 74 ``USStateField`` ``CharField`` with 75 ``widget=USStateSelect`` 76 (``USStateSelect`` is from 77 ``django.contrib.localflavor.us``) 78 ``XMLField`` ``CharField`` with ``widget=Textarea`` 79 =============================== ======================================== 80 81 82 .. note:: 83 The ``FloatField`` form field and ``DecimalField`` model and form fields 84 are new in the development version. 85 86 As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field 87 types are special cases: 88 89 * ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``, 90 which is a ``ChoiceField`` whose choices are a model ``QuerySet``. 91 92 * ``ManyToManyField`` is represented by 93 ``django.newforms.ModelMultipleChoiceField``, which is a 94 ``MultipleChoiceField`` whose choices are a model ``QuerySet``. 95 96 In addition, each generated form field has attributes set as follows: 97 98 * If the model field has ``blank=True``, then ``required`` is set to 99 ``False`` on the form field. Otherwise, ``required=True``. 100 101 * The form field's ``label`` is set to the ``verbose_name`` of the model 102 field, with the first character capitalized. 103 104 * The form field's ``help_text`` is set to the ``help_text`` of the model 105 field. 106 107 * If the model field has ``choices`` set, then the form field's ``widget`` 108 will be set to ``Select``, with choices coming from the model field's 109 ``choices``. The choices will normally include the blank choice which is 110 selected by default. If the field is required, this forces the user to 111 make a selection. The blank choice will not be included if the model 112 field has ``blank=False`` and an explicit ``default`` value (the 113 ``default`` value will be initially selected instead). 114 115 Finally, note that you can override the form field used for a given model 116 field. See "Overriding the default field types" below. 117 118 A full example 119 ~~~~~~~~~~~~~~ 120 121 Consider this set of models:: 122 123 from django.db import models 124 125 TITLE_CHOICES = ( 126 ('MR', 'Mr.'), 127 ('MRS', 'Mrs.'), 128 ('MS', 'Ms.'), 129 ) 130 131 class Author(models.Model): 132 name = models.CharField(max_length=100) 133 title = models.CharField(max_length=3, choices=TITLE_CHOICES) 134 birth_date = models.DateField(blank=True, null=True) 135 136 def __unicode__(self): 137 return self.name 138 139 class Book(models.Model): 140 name = models.CharField(max_length=100) 141 authors = models.ManyToManyField(Author) 142 143 With these models, a call to ``form_for_model(Author)`` would return a ``Form`` 144 class equivalent to this:: 145 146 class AuthorForm(forms.Form): 147 name = forms.CharField(max_length=100) 148 title = forms.CharField(max_length=3, 149 widget=forms.Select(choices=TITLE_CHOICES)) 150 birth_date = forms.DateField(required=False) 151 152 A call to ``form_for_model(Book)`` would return a ``Form`` class equivalent to 153 this:: 154 155 class BookForm(forms.Form): 156 name = forms.CharField(max_length=100) 157 authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all()) 158 159 The ``save()`` method 160 ~~~~~~~~~~~~~~~~~~~~~ 161 162 Every form produced by ``form_for_model()`` also has a ``save()`` method. This 163 method creates and saves a database object from the data bound to the form. For 164 example:: 165 166 # Create a form instance from POST data. 167 >>> f = ArticleForm(request.POST) 168 169 # Save a new Article object from the form's data. 170 >>> new_article = f.save() 171 172 Note that ``save()`` will raise a ``ValueError`` if the data in the form 173 doesn't validate -- i.e., ``if form.errors``. 174 175 This ``save()`` method accepts an optional ``commit`` keyword argument, which 176 accepts either ``True`` or ``False``. If you call ``save()`` with 177 ``commit=False``, then it will return an object that hasn't yet been saved to 178 the database. In this case, it's up to you to call ``save()`` on the resulting 179 model instance. This is useful if you want to do custom processing on the 180 object before saving it. ``commit`` is ``True`` by default. 181 182 Another side effect of using ``commit=False`` is seen when your model has 183 a many-to-many relation with another model. If your model has a many-to-many 184 relation and you specify ``commit=False`` when you save a form, Django cannot 185 immediately save the form data for the many-to-many relation. This is because 186 it isn't possible to save many-to-many data for an instance until the instance 187 exists in the database. 188 189 To work around this problem, every time you save a form using ``commit=False``, 190 Django adds a ``save_m2m()`` method to the form created by ``form_for_model``. 191 After you've manually saved the instance produced by the form, you can invoke 192 ``save_m2m()`` to save the many-to-many form data. For example:: 193 194 # Create a form instance with POST data. 195 >>> f = AuthorForm(request.POST) 196 197 # Create, but don't save the new author instance. 198 >>> new_author = f.save(commit=False) 199 200 # Modify the author in some way. 201 >>> new_author.some_field = 'some_value' 202 203 # Save the new instance. 204 >>> new_author.save() 205 206 # Now, save the many-to-many data for the form. 207 >>> f.save_m2m() 208 209 Calling ``save_m2m()`` is only required if you use ``save(commit=False)``. 210 When you use a simple ``save()`` on a form, all data -- including 211 many-to-many data -- is saved without the need for any additional method calls. 212 For example:: 213 214 # Create a form instance with POST data. 215 >>> f = AuthorForm(request.POST) 216 217 # Create and save the new author instance. There's no need to do anything else. 218 >>> new_author = f.save() 219 220 Using an alternate base class 221 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 222 223 If you want to add custom methods to the form generated by 224 ``form_for_model()``, write a class that extends ``django.newforms.BaseForm`` 225 and contains your custom methods. Then, use the ``form`` argument to 226 ``form_for_model()`` to tell it to use your custom form as its base class. 227 For example:: 228 229 # Create the new base class. 230 >>> class MyBase(BaseForm): 231 ... def my_method(self): 232 ... # Do whatever the method does 233 234 # Create the form class with a different base class. 235 >>> ArticleForm = form_for_model(Article, form=MyBase) 236 237 # Instantiate the form. 238 >>> f = ArticleForm() 239 240 # Use the base class method. 241 >>> f.my_method() 242 243 Using a subset of fields on the form 244 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 245 246 **New in Django development version** 247 248 In some cases, you may not want all the model fields to appear on the generated 249 form. There are two ways of telling ``form_for_model()`` to use only a subset 250 of the model fields: 251 252 1. Set ``editable=False`` on the model field. As a result, *any* form 253 created from the model via ``form_for_model()`` will not include that 254 field. 255 256 2. Use the ``fields`` argument to ``form_for_model()``. This argument, if 257 given, should be a list of field names to include in the form. 258 259 For example, if you want a form for the ``Author`` model (defined above) 260 that includes only the ``name`` and ``title`` fields, you would specify 261 ``fields`` like this:: 262 263 PartialArticleForm = form_for_model(Author, fields=('name', 'title')) 264 265 .. note:: 266 267 If you specify ``fields`` when creating a form with ``form_for_model()``, 268 then the fields that are *not* specified will not be set by the form's 269 ``save()`` method. Django will prevent any attempt to save an incomplete 270 model, so if the model does not allow the missing fields to be empty, and 271 does not provide a default value for the missing fields, any attempt to 272 ``save()`` a ``form_for_model`` with missing fields will fail. To avoid 273 this failure, you must use ``save(commit=False)`` and manually set any 274 extra required fields:: 275 276 instance = form.save(commit=False) 277 instance.required_field = 'new value' 278 instance.save() 279 280 See the `section on saving forms`_ for more details on using 281 ``save(commit=False)``. 282 283 .. _section on saving forms: `The save() method`_ 284 285 Overriding the default field types 286 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 287 288 The default field types, as described in the "Field types" table above, are 289 sensible defaults; if you have a ``DateField`` in your model, chances are you'd 290 want that to be represented as a ``DateField`` in your form. But 291 ``form_for_model()`` gives you the flexibility of changing the form field type 292 for a given model field. You do this by specifying a **formfield callback**. 293 294 A formfield callback is a function that, when provided with a model field, 295 returns a form field instance. When constructing a form, ``form_for_model()`` 296 asks the formfield callback to provide form field types. 297 298 By default, ``form_for_model()`` calls the ``formfield()`` method on the model 299 field:: 300 301 def default_callback(field, **kwargs): 302 return field.formfield(**kwargs) 303 304 The ``kwargs`` are any keyword arguments that might be passed to the form 305 field, such as ``required=True`` or ``label='Foo'``. 306 307 For example, if you wanted to use ``MyDateFormField`` for any ``DateField`` 308 field on the model, you could define the callback:: 309 310 >>> def my_callback(field, **kwargs): 311 ... if isinstance(field, models.DateField): 312 ... return MyDateFormField(**kwargs) 313 ... else: 314 ... return field.formfield(**kwargs) 315 316 >>> ArticleForm = form_for_model(Article, formfield_callback=my_callback) 317 318 Note that your callback needs to handle *all* possible model field types, not 319 just the ones that you want to behave differently to the default. That's why 320 this example has an ``else`` clause that implements the default behavior. 321 322 .. warning:: 323 The field that is passed into the ``formfield_callback`` function in 324 ``form_for_model()`` and ``form_for_instance`` is the field instance from 325 your model's class. You **must not** alter that object at all; treat it 326 as read-only! 327 328 If you make any alterations to that object, it will affect any future 329 users of the model class, because you will have changed the field object 330 used to construct the class. This is almost certainly what you don't want 331 to have happen. 332 333 Finding the model associated with a form 334 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 335 336 The model class that was used to construct the form is available 337 using the ``_model`` property of the generated form:: 338 339 >>> ArticleForm = form_for_model(Article) 340 >>> ArticleForm._model 341 <class 'myapp.models.Article'> 342 343 ``form_for_instance()`` 344 ----------------------- 345 346 ``form_for_instance()`` is like ``form_for_model()``, but it takes a model 347 instance instead of a model class:: 348 349 # Create an Author. 350 >>> a = Author(name='Joe Smith', title='MR', birth_date=None) 351 >>> a.save() 352 353 # Create a form for this particular Author. 354 >>> AuthorForm = form_for_instance(a) 355 356 # Instantiate the form. 357 >>> f = AuthorForm() 358 359 When a form created by ``form_for_instance()`` is created, the initial data 360 values for the form fields are drawn from the instance. However, this data is 361 not bound to the form. You will need to bind data to the form before the form 362 can be saved. 363 364 Unlike ``form_for_model()``, a choice field in form created by 365 ``form_for_instance()`` will not include the blank choice if the respective 366 model field has ``blank=False``. The initial choice is drawn from the instance. 367 368 When you call ``save()`` on a form created by ``form_for_instance()``, 369 the database instance will be updated. As in ``form_for_model()``, ``save()`` 370 will raise ``ValueError`` if the data doesn't validate. 371 372 ``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback`` 373 arguments that behave the same way as they do for ``form_for_model()``. 374 375 Let's modify the earlier `contact form`_ view example a little bit. Suppose we 376 have a ``Message`` model that holds each contact submission. Something like:: 377 378 class Message(models.Model): 379 subject = models.CharField(max_length=100) 380 message = models.TextField() 381 sender = models.EmailField() 382 cc_myself = models.BooleanField(required=False) 383 384 You could use this model to create a form (using ``form_for_model()``). You 385 could also use existing ``Message`` instances to create a form for editing 386 messages. The `simple example view`_ can be changed slightly to accept the ``id`` value 387 of an existing ``Message`` and present it for editing:: 388 389 def contact_edit(request, msg_id): 390 # Create the form from the message id. 391 message = get_object_or_404(Message, id=msg_id) 392 ContactForm = form_for_instance(message) 393 394 if request.method == 'POST': 395 form = ContactForm(request.POST) 396 if form.is_valid(): 397 form.save() 398 return HttpResponseRedirect('/url/on_success/') 399 else: 400 form = ContactForm() 401 return render_to_response('contact.html', {'form': form}) 402 403 Aside from how we create the ``ContactForm`` class here, the main point to 404 note is that the form display in the ``GET`` branch of the function 405 will use the values from the ``message`` instance as initial values for the 406 form field. 407 408 .. _contact form: ../newforms/#simple-view-example 409 .. _`simple example view`: ../newforms/#simple-view-example 410 411 When should you use ``form_for_model()`` and ``form_for_instance()``? 412 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 413 414 The ``form_for_model()`` and ``form_for_instance()`` functions are meant to be 415 shortcuts for the common case. If you want to create a form whose fields map to 416 more than one model, or a form that contains fields that *aren't* on a model, 417 you shouldn't use these shortcuts. Creating a ``Form`` class the "long" way 418 isn't that difficult, after all. -
new file docs/modelforms.txt
diff --git a/docs/modelforms.txt b/docs/modelforms.txt new file mode 100644 index 0000000..5e94128
- + 1 ========================== 2 Using newforms with models 3 ========================== 4 5 ``ModelForm`` 6 ============= 7 8 If you're building a database-driven app, chances are you'll have forms that 9 map closely to Django models. For instance, you might have a ``BlogComment`` 10 model, and you want to create a form that lets people submit comments. In this 11 case, it would be redundant to define the field types in your form, because 12 you've already defined the fields in your model. 13 14 For this reason, Django provides a helper class that let you create a ``Form`` 15 class from a Django model. 16 17 For example:: 18 19 >>> from django.newforms import ModelForm 20 21 # Create the form class. 22 >>> class ArticleForm(ModelForm): 23 ... class Meta: 24 ... model = Article 25 26 # Creating a form to add an article. 27 >>> article\ = Article() 28 >>> form = ArticleForm(article) 29 30 # Creating a form to change an existing article. 31 >>> article = Article.objects.get(pk=1) 32 >>> form = ArticleForm(article) 33 34 Field types 35 ----------- 36 37 The generated ``Form`` class will have a form field for every model field. Each 38 model field has a corresponding default form field. For example, a 39 ``CharField`` on a model is represented as a ``CharField`` on a form. A 40 model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is 41 the full list of conversions: 42 43 =============================== ======================================== 44 Model field Form field 45 =============================== ======================================== 46 ``AutoField`` Not represented in the form 47 ``BooleanField`` ``BooleanField`` 48 ``CharField`` ``CharField`` with ``max_length`` set to 49 the model field's ``max_length`` 50 ``CommaSeparatedIntegerField`` ``CharField`` 51 ``DateField`` ``DateField`` 52 ``DateTimeField`` ``DateTimeField`` 53 ``DecimalField`` ``DecimalField`` 54 ``EmailField`` ``EmailField`` 55 ``FileField`` ``FileField`` 56 ``FilePathField`` ``CharField`` 57 ``FloatField`` ``FloatField`` 58 ``ForeignKey`` ``ModelChoiceField`` (see below) 59 ``ImageField`` ``ImageField`` 60 ``IntegerField`` ``IntegerField`` 61 ``IPAddressField`` ``IPAddressField`` 62 ``ManyToManyField`` ``ModelMultipleChoiceField`` (see 63 below) 64 ``NullBooleanField`` ``CharField`` 65 ``PhoneNumberField`` ``USPhoneNumberField`` 66 (from ``django.contrib.localflavor.us``) 67 ``PositiveIntegerField`` ``IntegerField`` 68 ``PositiveSmallIntegerField`` ``IntegerField`` 69 ``SlugField`` ``CharField`` 70 ``SmallIntegerField`` ``IntegerField`` 71 ``TextField`` ``CharField`` with ``widget=Textarea`` 72 ``TimeField`` ``TimeField`` 73 ``URLField`` ``URLField`` with ``verify_exists`` set 74 to the model field's ``verify_exists`` 75 ``USStateField`` ``CharField`` with 76 ``widget=USStateSelect`` 77 (``USStateSelect`` is from 78 ``django.contrib.localflavor.us``) 79 ``XMLField`` ``CharField`` with ``widget=Textarea`` 80 =============================== ======================================== 81 82 83 .. note:: 84 The ``FloatField`` form field and ``DecimalField`` model and form fields 85 are new in the development version. 86 87 As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field 88 types are special cases: 89 90 * ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``, 91 which is a ``ChoiceField`` whose choices are a model ``QuerySet``. 92 93 * ``ManyToManyField`` is represented by 94 ``django.newforms.ModelMultipleChoiceField``, which is a 95 ``MultipleChoiceField`` whose choices are a model ``QuerySet``. 96 97 In addition, each generated form field has attributes set as follows: 98 99 * If the model field has ``blank=True``, then ``required`` is set to 100 ``False`` on the form field. Otherwise, ``required=True``. 101 102 * The form field's ``label`` is set to the ``verbose_name`` of the model 103 field, with the first character capitalized. 104 105 * The form field's ``help_text`` is set to the ``help_text`` of the model 106 field. 107 108 * If the model field has ``choices`` set, then the form field's ``widget`` 109 will be set to ``Select``, with choices coming from the model field's 110 ``choices``. The choices will normally include the blank choice which is 111 selected by default. If the field is required, this forces the user to 112 make a selection. The blank choice will not be included if the model 113 field has ``blank=False`` and an explicit ``default`` value (the 114 ``default`` value will be initially selected instead). 115 116 Finally, note that you can override the form field used for a given model 117 field. See "Overriding the default field types" below. 118 119 A full example 120 -------------- 121 122 Consider this set of models:: 123 124 from django.db import models 125 126 TITLE_CHOICES = ( 127 ('MR', 'Mr.'), 128 ('MRS', 'Mrs.'), 129 ('MS', 'Ms.'), 130 ) 131 132 class Author(models.Model): 133 name = models.CharField(max_length=100) 134 title = models.CharField(max_length=3, choices=TITLE_CHOICES) 135 birth_date = models.DateField(blank=True, null=True) 136 137 def __unicode__(self): 138 return self.name 139 140 class Book(models.Model): 141 name = models.CharField(max_length=100) 142 authors = models.ManyToManyField(Author) 143 144 class AuthorForm(ModelForm): 145 class Meta: 146 model = Author 147 148 class BookForm(ModelForm): 149 class Meta: 150 model = Book 151 152 With these models, the ``ModelForm`` subclasses above would be roughly 153 equivalent to this (the only difference being the ``save()`` method, which 154 we'll discuss in a moment.):: 155 156 class AuthorForm(forms.Form): 157 name = forms.CharField(max_length=100) 158 title = forms.CharField(max_length=3, 159 widget=forms.Select(choices=TITLE_CHOICES)) 160 birth_date = forms.DateField(required=False) 161 162 class BookForm(forms.Form): 163 name = forms.CharField(max_length=100) 164 authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all()) 165 166 The ``save()`` method 167 --------------------- 168 169 Every form produced by ``ModelForm`` also has a ``save()`` method. This 170 method creates and saves a database object from the data bound to the form. 171 A subclass of ``ModelForm`` also requires a model instance as the first 172 arument to its constructor. For example:: 173 174 # Create a form instance from POST data. 175 >>> a = Article() 176 >>> f = ArticleForm(a, request.POST) 177 178 # Save a new Article object from the form's data. 179 >>> new_article = f.save() 180 181 Note that ``save()`` will raise a ``ValueError`` if the data in the form 182 doesn't validate -- i.e., ``if form.errors``. 183 184 This ``save()`` method accepts an optional ``commit`` keyword argument, which 185 accepts either ``True`` or ``False``. If you call ``save()`` with 186 ``commit=False``, then it will return an object that hasn't yet been saved to 187 the database. In this case, it's up to you to call ``save()`` on the resulting 188 model instance. This is useful if you want to do custom processing on the 189 object before saving it. ``commit`` is ``True`` by default. 190 191 Another side effect of using ``commit=False`` is seen when your model has 192 a many-to-many relation with another model. If your model has a many-to-many 193 relation and you specify ``commit=False`` when you save a form, Django cannot 194 immediately save the form data for the many-to-many relation. This is because 195 it isn't possible to save many-to-many data for an instance until the instance 196 exists in the database. 197 198 To work around this problem, every time you save a form using ``commit=False``, 199 Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After 200 you've manually saved the instance produced by the form, you can invoke 201 ``save_m2m()`` to save the many-to-many form data. For example:: 202 203 # Create a form instance with POST data. 204 >>> a = Author() 205 >>> f = AuthorForm(a, request.POST) 206 207 # Create, but don't save the new author instance. 208 >>> new_author = f.save(commit=False) 209 210 # Modify the author in some way. 211 >>> new_author.some_field = 'some_value' 212 213 # Save the new instance. 214 >>> new_author.save() 215 216 # Now, save the many-to-many data for the form. 217 >>> f.save_m2m() 218 219 Calling ``save_m2m()`` is only required if you use ``save(commit=False)``. 220 When you use a simple ``save()`` on a form, all data -- including 221 many-to-many data -- is saved without the need for any additional method calls. 222 For example:: 223 224 # Create a form instance with POST data. 225 >>> a = Author() 226 >>> f = AuthorForm(a, request.POST) 227 228 # Create and save the new author instance. There's no need to do anything else. 229 >>> new_author = f.save() 230 231 Using a subset of fields on the form 232 ------------------------------------ 233 234 In some cases, you may not want all the model fields to appear on the generated 235 form. There are three ways of telling ``ModelForm`` to use only a subset of the 236 model fields: 237 238 1. Set ``editable=False`` on the model field. As a result, *any* form 239 created from the model via ``ModelForm`` will not include that 240 field. 241 242 2. Use the ``fields`` attribute of the ``ModelForm``'s inner ``Meta`` class. 243 This attribute, if given, should be a list of field names to include in 244 the form. 245 246 3. Use the ``exclude`` attribute of the ``ModelForm``'s inner ``Meta`` class. 247 This attribute, if given, should be a list of field names to exclude 248 the form. 249 250 For example, if you want a form for the ``Author`` model (defined above) 251 that includes only the ``name`` and ``title`` fields, you would specify 252 ``fields`` or ``exclude`` like this:: 253 254 class PartialAuthorForm(ModelForm): 255 class Meta: 256 model = Author 257 fields = ('name', 'title') 258 259 class PartialAuthorForm(ModelForm): 260 class Meta: 261 model = Author 262 exclude = ('birth_date',) 263 264 Since the Author model has only 3 fields, 'name', 'title', and 265 'birth_date', the forms above will contain exactly the same fields. 266 267 .. note:: 268 269 If you specify ``fields`` or ``exclude`` when creating a form with 270 ``ModelForm``, then the fields that are not in the resulting form will not 271 be set by the form's ``save()`` method. Django will prevent any attempt to 272 save an incomplete model, so if the model does not allow the missing fields 273 to be empty, and does not provide a default value for the missing fields, 274 any attempt to ``save()`` a ``ModelForm`` with missing fields will fail. 275 To avoid this failure, you must instantiate your model with initial values 276 for the missing, but required fields, or use ``save(commit=False)`` and 277 manually set anyextra required fields:: 278 279 instance = Instance(requiured_field='value') 280 form = InstanceForm(instance, request.POST) 281 new_instance = form.save() 282 283 instance = form.save(commit=False) 284 instance.required_field = 'new value' 285 new_instance = instance.save() 286 287 See the `section on saving forms`_ for more details on using 288 ``save(commit=False)``. 289 290 .. _section on saving forms: `The save() method`_ 291 292 Overriding the default field types 293 ---------------------------------- 294 295 The default field types, as described in the "Field types" table above, are 296 sensible defaults; if you have a ``DateField`` in your model, chances are you'd 297 want that to be represented as a ``DateField`` in your form. But 298 ``ModelForm`` gives you the flexibility of changing the form field type 299 for a given model field. You do this by declaratively specifying fields like 300 you would in a regular ``Form``. Declared fields will override the default 301 ones generated by using the ``model`` attribute. 302 303 For example, if you wanted to use ``MyDateFormField`` for the ``pub_date`` 304 field, you could do the following:: 305 306 >>> class ArticleForm(ModelForm): 307 ... pub_date = MyDateFormField() 308 ... 309 ... class Meta: 310 ... model = Article -
docs/newforms.txt
diff --git a/docs/newforms.txt b/docs/newforms.txt index f26afcb..75573ac 100644
a b You can then use this field whenever you have a form that requires a comment:: 1768 1768 Generating forms for models 1769 1769 =========================== 1770 1770 1771 If you're building a database-driven app, chances are you'll have forms that 1772 map closely to Django models. For instance, you might have a ``BlogComment`` 1773 model, and you want to create a form that lets people submit comments. In this 1774 case, it would be redundant to define the field types in your form, because 1775 you've already defined the fields in your model. 1771 The prefered way of generating forms that work with models is explained in the 1772 `ModelForms documentation`_. 1776 1773 1777 For this reason, Django provides a few helper functions that let you create a 1778 ``Form`` class from a Django model.1774 Looking for the ``form_for_model`` and ``form_for_instance`` documentation? 1775 They've been deprecated, but you can still `view the documentation`_. 1779 1776 1780 ``form_for_model()`` 1781 -------------------- 1782 1783 The method ``django.newforms.form_for_model()`` creates a form based on the 1784 definition of a specific model. Pass it the model class, and it will return a 1785 ``Form`` class that contains a form field for each model field. 1786 1787 For example:: 1788 1789 >>> from django.newforms import form_for_model 1790 1791 # Create the form class. 1792 >>> ArticleForm = form_for_model(Article) 1793 1794 # Create an empty form instance. 1795 >>> f = ArticleForm() 1796 1797 It bears repeating that ``form_for_model()`` takes the model *class*, not a 1798 model instance, and it returns a ``Form`` *class*, not a ``Form`` instance. 1799 1800 Field types 1801 ~~~~~~~~~~~ 1802 1803 The generated ``Form`` class will have a form field for every model field. Each 1804 model field has a corresponding default form field. For example, a 1805 ``CharField`` on a model is represented as a ``CharField`` on a form. A 1806 model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is 1807 the full list of conversions: 1808 1809 =============================== ======================================== 1810 Model field Form field 1811 =============================== ======================================== 1812 ``AutoField`` Not represented in the form 1813 ``BooleanField`` ``BooleanField`` 1814 ``CharField`` ``CharField`` with ``max_length`` set to 1815 the model field's ``max_length`` 1816 ``CommaSeparatedIntegerField`` ``CharField`` 1817 ``DateField`` ``DateField`` 1818 ``DateTimeField`` ``DateTimeField`` 1819 ``DecimalField`` ``DecimalField`` 1820 ``EmailField`` ``EmailField`` 1821 ``FileField`` ``FileField`` 1822 ``FilePathField`` ``CharField`` 1823 ``FloatField`` ``FloatField`` 1824 ``ForeignKey`` ``ModelChoiceField`` (see below) 1825 ``ImageField`` ``ImageField`` 1826 ``IntegerField`` ``IntegerField`` 1827 ``IPAddressField`` ``IPAddressField`` 1828 ``ManyToManyField`` ``ModelMultipleChoiceField`` (see 1829 below) 1830 ``NullBooleanField`` ``CharField`` 1831 ``PhoneNumberField`` ``USPhoneNumberField`` 1832 (from ``django.contrib.localflavor.us``) 1833 ``PositiveIntegerField`` ``IntegerField`` 1834 ``PositiveSmallIntegerField`` ``IntegerField`` 1835 ``SlugField`` ``CharField`` 1836 ``SmallIntegerField`` ``IntegerField`` 1837 ``TextField`` ``CharField`` with ``widget=Textarea`` 1838 ``TimeField`` ``TimeField`` 1839 ``URLField`` ``URLField`` with ``verify_exists`` set 1840 to the model field's ``verify_exists`` 1841 ``USStateField`` ``CharField`` with 1842 ``widget=USStateSelect`` 1843 (``USStateSelect`` is from 1844 ``django.contrib.localflavor.us``) 1845 ``XMLField`` ``CharField`` with ``widget=Textarea`` 1846 =============================== ======================================== 1847 1848 1849 .. note:: 1850 The ``FloatField`` form field and ``DecimalField`` model and form fields 1851 are new in the development version. 1852 1853 As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field 1854 types are special cases: 1855 1856 * ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``, 1857 which is a ``ChoiceField`` whose choices are a model ``QuerySet``. 1858 1859 * ``ManyToManyField`` is represented by 1860 ``django.newforms.ModelMultipleChoiceField``, which is a 1861 ``MultipleChoiceField`` whose choices are a model ``QuerySet``. 1862 1863 In addition, each generated form field has attributes set as follows: 1864 1865 * If the model field has ``blank=True``, then ``required`` is set to 1866 ``False`` on the form field. Otherwise, ``required=True``. 1867 1868 * The form field's ``label`` is set to the ``verbose_name`` of the model 1869 field, with the first character capitalized. 1870 1871 * The form field's ``help_text`` is set to the ``help_text`` of the model 1872 field. 1873 1874 * If the model field has ``choices`` set, then the form field's ``widget`` 1875 will be set to ``Select``, with choices coming from the model field's 1876 ``choices``. The choices will normally include the blank choice which is 1877 selected by default. If the field is required, this forces the user to 1878 make a selection. The blank choice will not be included if the model 1879 field has ``blank=False`` and an explicit ``default`` value (the 1880 ``default`` value will be initially selected instead). 1881 1882 Finally, note that you can override the form field used for a given model 1883 field. See "Overriding the default field types" below. 1884 1885 A full example 1886 ~~~~~~~~~~~~~~ 1887 1888 Consider this set of models:: 1889 1890 from django.db import models 1891 1892 TITLE_CHOICES = ( 1893 ('MR', 'Mr.'), 1894 ('MRS', 'Mrs.'), 1895 ('MS', 'Ms.'), 1896 ) 1897 1898 class Author(models.Model): 1899 name = models.CharField(max_length=100) 1900 title = models.CharField(max_length=3, choices=TITLE_CHOICES) 1901 birth_date = models.DateField(blank=True, null=True) 1902 1903 def __unicode__(self): 1904 return self.name 1905 1906 class Book(models.Model): 1907 name = models.CharField(max_length=100) 1908 authors = models.ManyToManyField(Author) 1909 1910 With these models, a call to ``form_for_model(Author)`` would return a ``Form`` 1911 class equivalent to this:: 1912 1913 class AuthorForm(forms.Form): 1914 name = forms.CharField(max_length=100) 1915 title = forms.CharField(max_length=3, 1916 widget=forms.Select(choices=TITLE_CHOICES)) 1917 birth_date = forms.DateField(required=False) 1918 1919 A call to ``form_for_model(Book)`` would return a ``Form`` class equivalent to 1920 this:: 1921 1922 class BookForm(forms.Form): 1923 name = forms.CharField(max_length=100) 1924 authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all()) 1925 1926 The ``save()`` method 1927 ~~~~~~~~~~~~~~~~~~~~~ 1928 1929 Every form produced by ``form_for_model()`` also has a ``save()`` method. This 1930 method creates and saves a database object from the data bound to the form. For 1931 example:: 1932 1933 # Create a form instance from POST data. 1934 >>> f = ArticleForm(request.POST) 1935 1936 # Save a new Article object from the form's data. 1937 >>> new_article = f.save() 1938 1939 Note that ``save()`` will raise a ``ValueError`` if the data in the form 1940 doesn't validate -- i.e., ``if form.errors``. 1941 1942 This ``save()`` method accepts an optional ``commit`` keyword argument, which 1943 accepts either ``True`` or ``False``. If you call ``save()`` with 1944 ``commit=False``, then it will return an object that hasn't yet been saved to 1945 the database. In this case, it's up to you to call ``save()`` on the resulting 1946 model instance. This is useful if you want to do custom processing on the 1947 object before saving it. ``commit`` is ``True`` by default. 1948 1949 Another side effect of using ``commit=False`` is seen when your model has 1950 a many-to-many relation with another model. If your model has a many-to-many 1951 relation and you specify ``commit=False`` when you save a form, Django cannot 1952 immediately save the form data for the many-to-many relation. This is because 1953 it isn't possible to save many-to-many data for an instance until the instance 1954 exists in the database. 1955 1956 To work around this problem, every time you save a form using ``commit=False``, 1957 Django adds a ``save_m2m()`` method to the form created by ``form_for_model``. 1958 After you've manually saved the instance produced by the form, you can invoke 1959 ``save_m2m()`` to save the many-to-many form data. For example:: 1960 1961 # Create a form instance with POST data. 1962 >>> f = AuthorForm(request.POST) 1963 1964 # Create, but don't save the new author instance. 1965 >>> new_author = f.save(commit=False) 1966 1967 # Modify the author in some way. 1968 >>> new_author.some_field = 'some_value' 1969 1970 # Save the new instance. 1971 >>> new_author.save() 1972 1973 # Now, save the many-to-many data for the form. 1974 >>> f.save_m2m() 1975 1976 Calling ``save_m2m()`` is only required if you use ``save(commit=False)``. 1977 When you use a simple ``save()`` on a form, all data -- including 1978 many-to-many data -- is saved without the need for any additional method calls. 1979 For example:: 1980 1981 # Create a form instance with POST data. 1982 >>> f = AuthorForm(request.POST) 1983 1984 # Create and save the new author instance. There's no need to do anything else. 1985 >>> new_author = f.save() 1986 1987 Using an alternate base class 1988 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1989 1990 If you want to add custom methods to the form generated by 1991 ``form_for_model()``, write a class that extends ``django.newforms.BaseForm`` 1992 and contains your custom methods. Then, use the ``form`` argument to 1993 ``form_for_model()`` to tell it to use your custom form as its base class. 1994 For example:: 1995 1996 # Create the new base class. 1997 >>> class MyBase(BaseForm): 1998 ... def my_method(self): 1999 ... # Do whatever the method does 2000 2001 # Create the form class with a different base class. 2002 >>> ArticleForm = form_for_model(Article, form=MyBase) 2003 2004 # Instantiate the form. 2005 >>> f = ArticleForm() 2006 2007 # Use the base class method. 2008 >>> f.my_method() 2009 2010 Using a subset of fields on the form 2011 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2012 2013 **New in Django development version** 2014 2015 In some cases, you may not want all the model fields to appear on the generated 2016 form. There are two ways of telling ``form_for_model()`` to use only a subset 2017 of the model fields: 2018 2019 1. Set ``editable=False`` on the model field. As a result, *any* form 2020 created from the model via ``form_for_model()`` will not include that 2021 field. 2022 2023 2. Use the ``fields`` argument to ``form_for_model()``. This argument, if 2024 given, should be a list of field names to include in the form. 2025 2026 For example, if you want a form for the ``Author`` model (defined above) 2027 that includes only the ``name`` and ``title`` fields, you would specify 2028 ``fields`` like this:: 2029 2030 PartialArticleForm = form_for_model(Author, fields=('name', 'title')) 2031 2032 .. note:: 2033 2034 If you specify ``fields`` when creating a form with ``form_for_model()``, 2035 then the fields that are *not* specified will not be set by the form's 2036 ``save()`` method. Django will prevent any attempt to save an incomplete 2037 model, so if the model does not allow the missing fields to be empty, and 2038 does not provide a default value for the missing fields, any attempt to 2039 ``save()`` a ``form_for_model`` with missing fields will fail. To avoid 2040 this failure, you must use ``save(commit=False)`` and manually set any 2041 extra required fields:: 2042 2043 instance = form.save(commit=False) 2044 instance.required_field = 'new value' 2045 instance.save() 2046 2047 See the `section on saving forms`_ for more details on using 2048 ``save(commit=False)``. 2049 2050 .. _section on saving forms: `The save() method`_ 2051 2052 Overriding the default field types 2053 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2054 2055 The default field types, as described in the "Field types" table above, are 2056 sensible defaults; if you have a ``DateField`` in your model, chances are you'd 2057 want that to be represented as a ``DateField`` in your form. But 2058 ``form_for_model()`` gives you the flexibility of changing the form field type 2059 for a given model field. You do this by specifying a **formfield callback**. 2060 2061 A formfield callback is a function that, when provided with a model field, 2062 returns a form field instance. When constructing a form, ``form_for_model()`` 2063 asks the formfield callback to provide form field types. 2064 2065 By default, ``form_for_model()`` calls the ``formfield()`` method on the model 2066 field:: 2067 2068 def default_callback(field, **kwargs): 2069 return field.formfield(**kwargs) 2070 2071 The ``kwargs`` are any keyword arguments that might be passed to the form 2072 field, such as ``required=True`` or ``label='Foo'``. 2073 2074 For example, if you wanted to use ``MyDateFormField`` for any ``DateField`` 2075 field on the model, you could define the callback:: 2076 2077 >>> def my_callback(field, **kwargs): 2078 ... if isinstance(field, models.DateField): 2079 ... return MyDateFormField(**kwargs) 2080 ... else: 2081 ... return field.formfield(**kwargs) 2082 2083 >>> ArticleForm = form_for_model(Article, formfield_callback=my_callback) 2084 2085 Note that your callback needs to handle *all* possible model field types, not 2086 just the ones that you want to behave differently to the default. That's why 2087 this example has an ``else`` clause that implements the default behavior. 2088 2089 .. warning:: 2090 The field that is passed into the ``formfield_callback`` function in 2091 ``form_for_model()`` and ``form_for_instance`` is the field instance from 2092 your model's class. You **must not** alter that object at all; treat it 2093 as read-only! 2094 2095 If you make any alterations to that object, it will affect any future 2096 users of the model class, because you will have changed the field object 2097 used to construct the class. This is almost certainly what you don't want 2098 to have happen. 2099 2100 Finding the model associated with a form 2101 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2102 2103 The model class that was used to construct the form is available 2104 using the ``_model`` property of the generated form:: 2105 2106 >>> ArticleForm = form_for_model(Article) 2107 >>> ArticleForm._model 2108 <class 'myapp.models.Article'> 2109 2110 ``form_for_instance()`` 2111 ----------------------- 2112 2113 ``form_for_instance()`` is like ``form_for_model()``, but it takes a model 2114 instance instead of a model class:: 2115 2116 # Create an Author. 2117 >>> a = Author(name='Joe Smith', title='MR', birth_date=None) 2118 >>> a.save() 2119 2120 # Create a form for this particular Author. 2121 >>> AuthorForm = form_for_instance(a) 2122 2123 # Instantiate the form. 2124 >>> f = AuthorForm() 2125 2126 When a form created by ``form_for_instance()`` is created, the initial data 2127 values for the form fields are drawn from the instance. However, this data is 2128 not bound to the form. You will need to bind data to the form before the form 2129 can be saved. 2130 2131 Unlike ``form_for_model()``, a choice field in form created by 2132 ``form_for_instance()`` will not include the blank choice if the respective 2133 model field has ``blank=False``. The initial choice is drawn from the instance. 2134 2135 When you call ``save()`` on a form created by ``form_for_instance()``, 2136 the database instance will be updated. As in ``form_for_model()``, ``save()`` 2137 will raise ``ValueError`` if the data doesn't validate. 2138 2139 ``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback`` 2140 arguments that behave the same way as they do for ``form_for_model()``. 2141 2142 Let's modify the earlier `contact form`_ view example a little bit. Suppose we 2143 have a ``Message`` model that holds each contact submission. Something like:: 2144 2145 class Message(models.Model): 2146 subject = models.CharField(max_length=100) 2147 message = models.TextField() 2148 sender = models.EmailField() 2149 cc_myself = models.BooleanField(required=False) 2150 2151 You could use this model to create a form (using ``form_for_model()``). You 2152 could also use existing ``Message`` instances to create a form for editing 2153 messages. The earlier_ view can be changed slightly to accept the ``id`` value 2154 of an existing ``Message`` and present it for editing:: 2155 2156 def contact_edit(request, msg_id): 2157 # Create the form from the message id. 2158 message = get_object_or_404(Message, id=msg_id) 2159 ContactForm = form_for_instance(message) 2160 2161 if request.method == 'POST': 2162 form = ContactForm(request.POST) 2163 if form.is_valid(): 2164 form.save() 2165 return HttpResponseRedirect('/url/on_success/') 2166 else: 2167 form = ContactForm() 2168 return render_to_response('contact.html', {'form': form}) 2169 2170 Aside from how we create the ``ContactForm`` class here, the main point to 2171 note is that the form display in the ``GET`` branch of the function 2172 will use the values from the ``message`` instance as initial values for the 2173 form field. 2174 2175 .. _contact form: `Simple view example`_ 2176 .. _earlier: `Simple view example`_ 2177 2178 When should you use ``form_for_model()`` and ``form_for_instance()``? 2179 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2180 2181 The ``form_for_model()`` and ``form_for_instance()`` functions are meant to be 2182 shortcuts for the common case. If you want to create a form whose fields map to 2183 more than one model, or a form that contains fields that *aren't* on a model, 2184 you shouldn't use these shortcuts. Creating a ``Form`` class the "long" way 2185 isn't that difficult, after all. 1777 .. _ModelForms documentation: ../modelforms/ 1778 .. _view the documentation: ../form_for_model/ 2186 1779 2187 1780 More coming soon 2188 1781 ================ -
new file tests/modeltests/model_forms_new/models.py
diff --git a/tests/modeltests/model_forms_new/__init__.py b/tests/modeltests/model_forms_new/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/modeltests/model_forms_new/models.py b/tests/modeltests/model_forms_new/models.py new file mode 100644 index 0000000..bd611ed
- + 1 """ 2 XX. Generating HTML forms from models 3 4 This is mostly just a reworking of the form_for_model/form_for_instance tests 5 to use ModelForm. As such, the text may not make sense in all cases, and the 6 examples are probably a poor fit for the ModelForm syntax. In other words, 7 most of these tests should be rewritten. 8 """ 9 10 from django.db import models 11 12 ARTICLE_STATUS = ( 13 (1, 'Draft'), 14 (2, 'Pending'), 15 (3, 'Live'), 16 ) 17 18 class Category(models.Model): 19 name = models.CharField(max_length=20) 20 slug = models.SlugField(max_length=20) 21 url = models.CharField('The URL', max_length=40) 22 23 def __unicode__(self): 24 return self.name 25 26 class Writer(models.Model): 27 name = models.CharField(max_length=50, help_text='Use both first and last names.') 28 29 def __unicode__(self): 30 return self.name 31 32 class Article(models.Model): 33 headline = models.CharField(max_length=50) 34 slug = models.SlugField() 35 pub_date = models.DateField() 36 created = models.DateField(editable=False) 37 writer = models.ForeignKey(Writer) 38 article = models.TextField() 39 categories = models.ManyToManyField(Category, blank=True) 40 status = models.IntegerField(choices=ARTICLE_STATUS, blank=True, null=True) 41 42 def save(self): 43 import datetime 44 if not self.id: 45 self.created = datetime.date.today() 46 return super(Article, self).save() 47 48 def __unicode__(self): 49 return self.headline 50 51 class PhoneNumber(models.Model): 52 phone = models.PhoneNumberField() 53 description = models.CharField(max_length=20) 54 55 def __unicode__(self): 56 return self.phone 57 58 __test__ = {'API_TESTS': """ 59 >>> from django import newforms as forms 60 >>> from django.newforms.models import ModelForm 61 62 The bare bones, absolutely nothing custom, basic case. 63 64 >>> class CategoryForm(ModelForm): 65 ... class Meta: 66 ... model = Category 67 >>> CategoryForm.base_fields.keys() 68 ['name', 'slug', 'url'] 69 70 71 Extra fields. 72 73 >>> class CategoryForm(ModelForm): 74 ... some_extra_field = forms.BooleanField() 75 ... 76 ... class Meta: 77 ... model = Category 78 79 >>> CategoryForm.base_fields.keys() 80 ['name', 'slug', 'url', 'some_extra_field'] 81 82 83 Replacing a field. 84 85 >>> class CategoryForm(ModelForm): 86 ... url = forms.BooleanField() 87 ... 88 ... class Meta: 89 ... model = Category 90 91 >>> CategoryForm.base_fields['url'].__class__ 92 <class 'django.newforms.fields.BooleanField'> 93 94 95 Using 'fields'. 96 97 >>> class CategoryForm(ModelForm): 98 ... 99 ... class Meta: 100 ... model = Category 101 ... fields = ['url'] 102 103 >>> CategoryForm.base_fields.keys() 104 ['url'] 105 106 107 Using 'exclude' 108 109 >>> class CategoryForm(ModelForm): 110 ... 111 ... class Meta: 112 ... model = Category 113 ... exclude = ['url'] 114 115 >>> CategoryForm.base_fields.keys() 116 ['name', 'slug'] 117 118 119 Using 'fields' *and* 'exclude'. Not sure why you'd want to do this, but uh, 120 "be liberal in what you accept" and all. 121 122 >>> class CategoryForm(ModelForm): 123 ... 124 ... class Meta: 125 ... model = Category 126 ... fields = ['name', 'url'] 127 ... exclude = ['url'] 128 129 >>> CategoryForm.base_fields.keys() 130 ['name'] 131 132 Don't allow more than one 'model' defenition in the inheritance hierarchy. 133 Technically, it would generate a valid form, but the fact that the resulting 134 save method won't deal with multiple objects is likely to trip up people not 135 familiar with the mechanics. 136 137 >>> class CategoryForm(ModelForm): 138 ... class Meta: 139 ... model = Category 140 141 >>> class BadForm(CategoryForm): 142 ... class Meta: 143 ... model = Article 144 Traceback (most recent call last): 145 ... 146 ImproperlyConfigured: BadForm defines more than one model. 147 148 >>> class ArticleForm(ModelForm): 149 ... class Meta: 150 ... model = Article 151 152 >>> class BadForm(ArticleForm, CategoryForm): 153 ... pass 154 Traceback (most recent call last): 155 ... 156 ImproperlyConfigured: BadForm's base classes define more than one model. 157 158 159 # Old form_for_x tests ####################################################### 160 161 >>> from django.newforms import ModelForm, CharField 162 >>> import datetime 163 164 >>> Category.objects.all() 165 [] 166 167 >>> class CategoryForm(ModelForm): 168 ... class Meta: 169 ... model = Category 170 >>> f = CategoryForm(Category()) 171 >>> print f 172 <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr> 173 <tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr> 174 <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> 175 >>> print f.as_ul() 176 <li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" maxlength="20" /></li> 177 <li><label for="id_slug">Slug:</label> <input id="id_slug" type="text" name="slug" maxlength="20" /></li> 178 <li><label for="id_url">The URL:</label> <input id="id_url" type="text" name="url" maxlength="40" /></li> 179 >>> print f['name'] 180 <input id="id_name" type="text" name="name" maxlength="20" /> 181 182 >>> f = CategoryForm(Category(), auto_id=False) 183 >>> print f.as_ul() 184 <li>Name: <input type="text" name="name" maxlength="20" /></li> 185 <li>Slug: <input type="text" name="slug" maxlength="20" /></li> 186 <li>The URL: <input type="text" name="url" maxlength="40" /></li> 187 188 >>> f = CategoryForm(Category(), {'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'}) 189 >>> f.is_valid() 190 True 191 >>> f.cleaned_data 192 {'url': u'entertainment', 'name': u'Entertainment', 'slug': u'entertainment'} 193 >>> obj = f.save() 194 >>> obj 195 <Category: Entertainment> 196 >>> Category.objects.all() 197 [<Category: Entertainment>] 198 199 >>> f = CategoryForm(Category(), {'name': "It's a test", 'slug': 'its-test', 'url': 'test'}) 200 >>> f.is_valid() 201 True 202 >>> f.cleaned_data 203 {'url': u'test', 'name': u"It's a test", 'slug': u'its-test'} 204 >>> obj = f.save() 205 >>> obj 206 <Category: It's a test> 207 >>> Category.objects.order_by('name') 208 [<Category: Entertainment>, <Category: It's a test>] 209 210 If you call save() with commit=False, then it will return an object that 211 hasn't yet been saved to the database. In this case, it's up to you to call 212 save() on the resulting model instance. 213 >>> f = CategoryForm(Category(), {'name': 'Third test', 'slug': 'third-test', 'url': 'third'}) 214 >>> f.is_valid() 215 True 216 >>> f.cleaned_data 217 {'url': u'third', 'name': u'Third test', 'slug': u'third-test'} 218 >>> obj = f.save(commit=False) 219 >>> obj 220 <Category: Third test> 221 >>> Category.objects.order_by('name') 222 [<Category: Entertainment>, <Category: It's a test>] 223 >>> obj.save() 224 >>> Category.objects.order_by('name') 225 [<Category: Entertainment>, <Category: It's a test>, <Category: Third test>] 226 227 If you call save() with invalid data, you'll get a ValueError. 228 >>> f = CategoryForm(Category(), {'name': '', 'slug': '', 'url': 'foo'}) 229 >>> f.errors 230 {'name': [u'This field is required.'], 'slug': [u'This field is required.']} 231 >>> f.cleaned_data 232 Traceback (most recent call last): 233 ... 234 AttributeError: 'CategoryForm' object has no attribute 'cleaned_data' 235 >>> f.save() 236 Traceback (most recent call last): 237 ... 238 ValueError: The Category could not be created because the data didn't validate. 239 >>> f = CategoryForm(Category(), {'name': '', 'slug': '', 'url': 'foo'}) 240 >>> f.save() 241 Traceback (most recent call last): 242 ... 243 ValueError: The Category could not be created because the data didn't validate. 244 245 Create a couple of Writers. 246 >>> w = Writer(name='Mike Royko') 247 >>> w.save() 248 >>> w = Writer(name='Bob Woodward') 249 >>> w.save() 250 251 ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any 252 fields with the 'choices' attribute are represented by a ChoiceField. 253 >>> class ArticleForm(ModelForm): 254 ... class Meta: 255 ... model = Article 256 >>> f = ArticleForm(Article(), auto_id=False) 257 >>> print f 258 <tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr> 259 <tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr> 260 <tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr> 261 <tr><th>Writer:</th><td><select name="writer"> 262 <option value="" selected="selected">---------</option> 263 <option value="1">Mike Royko</option> 264 <option value="2">Bob Woodward</option> 265 </select></td></tr> 266 <tr><th>Article:</th><td><textarea rows="10" cols="40" name="article"></textarea></td></tr> 267 <tr><th>Status:</th><td><select name="status"> 268 <option value="" selected="selected">---------</option> 269 <option value="1">Draft</option> 270 <option value="2">Pending</option> 271 <option value="3">Live</option> 272 </select></td></tr> 273 <tr><th>Categories:</th><td><select multiple="multiple" name="categories"> 274 <option value="1">Entertainment</option> 275 <option value="2">It's a test</option> 276 <option value="3">Third test</option> 277 </select><br /> Hold down "Control", or "Command" on a Mac, to select more than one.</td></tr> 278 279 You can restrict a form to a subset of the complete list of fields 280 by providing a 'fields' argument. If you try to save a 281 model created with such a form, you need to ensure that the fields 282 that are _not_ on the form have default values, or are allowed to have 283 a value of None. If a field isn't specified on a form, the object created 284 from the form can't provide a value for that field! 285 >>> class PartialArticleForm(ModelForm): 286 ... class Meta: 287 ... model = Article 288 ... fields = ('headline','pub_date') 289 >>> f = PartialArticleForm(Article(), auto_id=False) 290 >>> print f 291 <tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr> 292 <tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr> 293 294 Use form_for_instance to create a Form from a model instance. The difference 295 between this Form and one created via form_for_model is that the object's 296 current values are inserted as 'initial' data in each Field. 297 >>> w = Writer.objects.get(name='Mike Royko') 298 >>> class RoykoForm(ModelForm): 299 ... class Meta: 300 ... model = Writer 301 >>> f = RoykoForm(w, auto_id=False) 302 >>> print f 303 <tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br />Use both first and last names.</td></tr> 304 305 >>> art = Article(headline='Test article', slug='test-article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.') 306 >>> art.save() 307 >>> art.id 308 1 309 >>> class TestArticleForm(ModelForm): 310 ... class Meta: 311 ... model = Article 312 >>> f = TestArticleForm(art, auto_id=False) 313 >>> print f.as_ul() 314 <li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /></li> 315 <li>Slug: <input type="text" name="slug" value="test-article" maxlength="50" /></li> 316 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li> 317 <li>Writer: <select name="writer"> 318 <option value="">---------</option> 319 <option value="1" selected="selected">Mike Royko</option> 320 <option value="2">Bob Woodward</option> 321 </select></li> 322 <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> 323 <li>Status: <select name="status"> 324 <option value="" selected="selected">---------</option> 325 <option value="1">Draft</option> 326 <option value="2">Pending</option> 327 <option value="3">Live</option> 328 </select></li> 329 <li>Categories: <select multiple="multiple" name="categories"> 330 <option value="1">Entertainment</option> 331 <option value="2">It's a test</option> 332 <option value="3">Third test</option> 333 </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> 334 >>> f = TestArticleForm(art, {'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': u'1', 'article': 'Hello.'}) 335 >>> f.is_valid() 336 True 337 >>> test_art = f.save() 338 >>> test_art.id 339 1 340 >>> test_art = Article.objects.get(id=1) 341 >>> test_art.headline 342 u'Test headline' 343 344 You can create a form over a subset of the available fields 345 by specifying a 'fields' argument to form_for_instance. 346 >>> class PartialArticleForm(ModelForm): 347 ... class Meta: 348 ... model = Article 349 ... fields=('headline', 'slug', 'pub_date') 350 >>> f = PartialArticleForm(art, {'headline': u'New headline', 'slug': 'new-headline', 'pub_date': u'1988-01-04'}, auto_id=False) 351 >>> print f.as_ul() 352 <li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li> 353 <li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li> 354 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li> 355 >>> f.is_valid() 356 True 357 >>> new_art = f.save() 358 >>> new_art.id 359 1 360 >>> new_art = Article.objects.get(id=1) 361 >>> new_art.headline 362 u'New headline' 363 364 Add some categories and test the many-to-many form output. 365 >>> new_art.categories.all() 366 [] 367 >>> new_art.categories.add(Category.objects.get(name='Entertainment')) 368 >>> new_art.categories.all() 369 [<Category: Entertainment>] 370 >>> class TestArticleForm(ModelForm): 371 ... class Meta: 372 ... model = Article 373 >>> f = TestArticleForm(new_art, auto_id=False) 374 >>> print f.as_ul() 375 <li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li> 376 <li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li> 377 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li> 378 <li>Writer: <select name="writer"> 379 <option value="">---------</option> 380 <option value="1" selected="selected">Mike Royko</option> 381 <option value="2">Bob Woodward</option> 382 </select></li> 383 <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> 384 <li>Status: <select name="status"> 385 <option value="" selected="selected">---------</option> 386 <option value="1">Draft</option> 387 <option value="2">Pending</option> 388 <option value="3">Live</option> 389 </select></li> 390 <li>Categories: <select multiple="multiple" name="categories"> 391 <option value="1" selected="selected">Entertainment</option> 392 <option value="2">It's a test</option> 393 <option value="3">Third test</option> 394 </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> 395 396 >>> f = TestArticleForm(new_art, {'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04', 397 ... 'writer': u'1', 'article': u'Hello.', 'categories': [u'1', u'2']}) 398 >>> new_art = f.save() 399 >>> new_art.id 400 1 401 >>> new_art = Article.objects.get(id=1) 402 >>> new_art.categories.order_by('name') 403 [<Category: Entertainment>, <Category: It's a test>] 404 405 Now, submit form data with no categories. This deletes the existing categories. 406 >>> f = TestArticleForm(new_art, {'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04', 407 ... 'writer': u'1', 'article': u'Hello.'}) 408 >>> new_art = f.save() 409 >>> new_art.id 410 1 411 >>> new_art = Article.objects.get(id=1) 412 >>> new_art.categories.all() 413 [] 414 415 Create a new article, with categories, via the form. 416 >>> class ArticleForm(ModelForm): 417 ... class Meta: 418 ... model = Article 419 >>> f = ArticleForm(Article(), {'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01', 420 ... 'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']}) 421 >>> new_art = f.save() 422 >>> new_art.id 423 2 424 >>> new_art = Article.objects.get(id=2) 425 >>> new_art.categories.order_by('name') 426 [<Category: Entertainment>, <Category: It's a test>] 427 428 Create a new article, with no categories, via the form. 429 >>> class ArticleForm(ModelForm): 430 ... class Meta: 431 ... model = Article 432 >>> f = ArticleForm(Article(), {'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01', 433 ... 'writer': u'1', 'article': u'Test.'}) 434 >>> new_art = f.save() 435 >>> new_art.id 436 3 437 >>> new_art = Article.objects.get(id=3) 438 >>> new_art.categories.all() 439 [] 440 441 Create a new article, with categories, via the form, but use commit=False. 442 The m2m data won't be saved until save_m2m() is invoked on the form. 443 >>> class ArticleForm(ModelForm): 444 ... class Meta: 445 ... model = Article 446 >>> f = ArticleForm(Article(), {'headline': u'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': u'1967-11-01', 447 ... 'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']}) 448 >>> new_art = f.save(commit=False) 449 450 # Manually save the instance 451 >>> new_art.save() 452 >>> new_art.id 453 4 454 455 # The instance doesn't have m2m data yet 456 >>> new_art = Article.objects.get(id=4) 457 >>> new_art.categories.all() 458 [] 459 460 # Save the m2m data on the form 461 >>> f.save_m2m() 462 >>> new_art.categories.order_by('name') 463 [<Category: Entertainment>, <Category: It's a test>] 464 465 Here, we define a custom ModelForm. Because it happens to have the same fields as 466 the Category model, we can just call the form's save() to apply its changes to an 467 existing Category instance. 468 >>> class ShortCategory(ModelForm): 469 ... name = CharField(max_length=5) 470 ... slug = CharField(max_length=5) 471 ... url = CharField(max_length=3) 472 >>> cat = Category.objects.get(name='Third test') 473 >>> cat 474 <Category: Third test> 475 >>> cat.id 476 3 477 >>> form = ShortCategory(cat, {'name': 'Third', 'slug': 'third', 'url': '3rd'}) 478 >>> form.save() 479 <Category: Third> 480 >>> Category.objects.get(id=3) 481 <Category: Third> 482 483 Here, we demonstrate that choices for a ForeignKey ChoiceField are determined 484 at runtime, based on the data in the database when the form is displayed, not 485 the data in the database when the form is instantiated. 486 >>> class ArticleForm(ModelForm): 487 ... class Meta: 488 ... model = Article 489 >>> f = ArticleForm(Article(), auto_id=False) 490 >>> print f.as_ul() 491 <li>Headline: <input type="text" name="headline" maxlength="50" /></li> 492 <li>Slug: <input type="text" name="slug" maxlength="50" /></li> 493 <li>Pub date: <input type="text" name="pub_date" /></li> 494 <li>Writer: <select name="writer"> 495 <option value="" selected="selected">---------</option> 496 <option value="1">Mike Royko</option> 497 <option value="2">Bob Woodward</option> 498 </select></li> 499 <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> 500 <li>Status: <select name="status"> 501 <option value="" selected="selected">---------</option> 502 <option value="1">Draft</option> 503 <option value="2">Pending</option> 504 <option value="3">Live</option> 505 </select></li> 506 <li>Categories: <select multiple="multiple" name="categories"> 507 <option value="1">Entertainment</option> 508 <option value="2">It's a test</option> 509 <option value="3">Third</option> 510 </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> 511 >>> Category.objects.create(name='Fourth', url='4th') 512 <Category: Fourth> 513 >>> Writer.objects.create(name='Carl Bernstein') 514 <Writer: Carl Bernstein> 515 >>> print f.as_ul() 516 <li>Headline: <input type="text" name="headline" maxlength="50" /></li> 517 <li>Slug: <input type="text" name="slug" maxlength="50" /></li> 518 <li>Pub date: <input type="text" name="pub_date" /></li> 519 <li>Writer: <select name="writer"> 520 <option value="" selected="selected">---------</option> 521 <option value="1">Mike Royko</option> 522 <option value="2">Bob Woodward</option> 523 <option value="3">Carl Bernstein</option> 524 </select></li> 525 <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> 526 <li>Status: <select name="status"> 527 <option value="" selected="selected">---------</option> 528 <option value="1">Draft</option> 529 <option value="2">Pending</option> 530 <option value="3">Live</option> 531 </select></li> 532 <li>Categories: <select multiple="multiple" name="categories"> 533 <option value="1">Entertainment</option> 534 <option value="2">It's a test</option> 535 <option value="3">Third</option> 536 <option value="4">Fourth</option> 537 </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> 538 539 # ModelChoiceField ############################################################ 540 541 >>> from django.newforms import ModelChoiceField, ModelMultipleChoiceField 542 543 >>> f = ModelChoiceField(Category.objects.all()) 544 >>> list(f.choices) 545 [(u'', u'---------'), (1, u'Entertainment'), (2, u"It's a test"), (3, u'Third'), (4, u'Fourth')] 546 >>> f.clean('') 547 Traceback (most recent call last): 548 ... 549 ValidationError: [u'This field is required.'] 550 >>> f.clean(None) 551 Traceback (most recent call last): 552 ... 553 ValidationError: [u'This field is required.'] 554 >>> f.clean(0) 555 Traceback (most recent call last): 556 ... 557 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] 558 >>> f.clean(3) 559 <Category: Third> 560 >>> f.clean(2) 561 <Category: It's a test> 562 563 # Add a Category object *after* the ModelChoiceField has already been 564 # instantiated. This proves clean() checks the database during clean() rather 565 # than caching it at time of instantiation. 566 >>> Category.objects.create(name='Fifth', url='5th') 567 <Category: Fifth> 568 >>> f.clean(5) 569 <Category: Fifth> 570 571 # Delete a Category object *after* the ModelChoiceField has already been 572 # instantiated. This proves clean() checks the database during clean() rather 573 # than caching it at time of instantiation. 574 >>> Category.objects.get(url='5th').delete() 575 >>> f.clean(5) 576 Traceback (most recent call last): 577 ... 578 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] 579 580 >>> f = ModelChoiceField(Category.objects.filter(pk=1), required=False) 581 >>> print f.clean('') 582 None 583 >>> f.clean('') 584 >>> f.clean('1') 585 <Category: Entertainment> 586 >>> f.clean('100') 587 Traceback (most recent call last): 588 ... 589 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] 590 591 # queryset can be changed after the field is created. 592 >>> f.queryset = Category.objects.exclude(name='Fourth') 593 >>> list(f.choices) 594 [(u'', u'---------'), (1, u'Entertainment'), (2, u"It's a test"), (3, u'Third')] 595 >>> f.clean(3) 596 <Category: Third> 597 >>> f.clean(4) 598 Traceback (most recent call last): 599 ... 600 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] 601 602 603 # ModelMultipleChoiceField #################################################### 604 605 >>> f = ModelMultipleChoiceField(Category.objects.all()) 606 >>> list(f.choices) 607 [(1, u'Entertainment'), (2, u"It's a test"), (3, u'Third'), (4, u'Fourth')] 608 >>> f.clean(None) 609 Traceback (most recent call last): 610 ... 611 ValidationError: [u'This field is required.'] 612 >>> f.clean([]) 613 Traceback (most recent call last): 614 ... 615 ValidationError: [u'This field is required.'] 616 >>> f.clean([1]) 617 [<Category: Entertainment>] 618 >>> f.clean([2]) 619 [<Category: It's a test>] 620 >>> f.clean(['1']) 621 [<Category: Entertainment>] 622 >>> f.clean(['1', '2']) 623 [<Category: Entertainment>, <Category: It's a test>] 624 >>> f.clean([1, '2']) 625 [<Category: Entertainment>, <Category: It's a test>] 626 >>> f.clean((1, '2')) 627 [<Category: Entertainment>, <Category: It's a test>] 628 >>> f.clean(['100']) 629 Traceback (most recent call last): 630 ... 631 ValidationError: [u'Select a valid choice. 100 is not one of the available choices.'] 632 >>> f.clean('hello') 633 Traceback (most recent call last): 634 ... 635 ValidationError: [u'Enter a list of values.'] 636 637 # Add a Category object *after* the ModelMultipleChoiceField has already been 638 # instantiated. This proves clean() checks the database during clean() rather 639 # than caching it at time of instantiation. 640 >>> Category.objects.create(id=6, name='Sixth', url='6th') 641 <Category: Sixth> 642 >>> f.clean([6]) 643 [<Category: Sixth>] 644 645 # Delete a Category object *after* the ModelMultipleChoiceField has already been 646 # instantiated. This proves clean() checks the database during clean() rather 647 # than caching it at time of instantiation. 648 >>> Category.objects.get(url='6th').delete() 649 >>> f.clean([6]) 650 Traceback (most recent call last): 651 ... 652 ValidationError: [u'Select a valid choice. 6 is not one of the available choices.'] 653 654 >>> f = ModelMultipleChoiceField(Category.objects.all(), required=False) 655 >>> f.clean([]) 656 [] 657 >>> f.clean(()) 658 [] 659 >>> f.clean(['10']) 660 Traceback (most recent call last): 661 ... 662 ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] 663 >>> f.clean(['3', '10']) 664 Traceback (most recent call last): 665 ... 666 ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] 667 >>> f.clean(['1', '10']) 668 Traceback (most recent call last): 669 ... 670 ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] 671 672 # queryset can be changed after the field is created. 673 >>> f.queryset = Category.objects.exclude(name='Fourth') 674 >>> list(f.choices) 675 [(1, u'Entertainment'), (2, u"It's a test"), (3, u'Third')] 676 >>> f.clean([3]) 677 [<Category: Third>] 678 >>> f.clean([4]) 679 Traceback (most recent call last): 680 ... 681 ValidationError: [u'Select a valid choice. 4 is not one of the available choices.'] 682 >>> f.clean(['3', '4']) 683 Traceback (most recent call last): 684 ... 685 ValidationError: [u'Select a valid choice. 4 is not one of the available choices.'] 686 687 688 # PhoneNumberField ############################################################ 689 690 >>> class PhoneNumberForm(ModelForm): 691 ... class Meta: 692 ... model = PhoneNumber 693 >>> f = PhoneNumberForm(PhoneNumber(), {'phone': '(312) 555-1212', 'description': 'Assistance'}) 694 >>> f.is_valid() 695 True 696 >>> f.cleaned_data 697 {'phone': u'312-555-1212', 'description': u'Assistance'} 698 """}