Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #6162. ModelForm's __init__ signature now matches Form's. This …

…is a backwards incompatbile change. Based largely on a patch by ubernostrum.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6915 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e415eff0ead50882525129b0d5fd8ca95f1d30a7 1 parent f9410dc
Joseph Kocherhans authored December 13, 2007
13  django/newforms/models.py
@@ -262,11 +262,16 @@ def __new__(cls, name, bases, attrs):
262 262
         return type.__new__(cls, name, bases, attrs)
263 263
 
264 264
 class BaseModelForm(BaseForm):
265  
-    def __init__(self, instance, data=None, files=None, auto_id='id_%s', prefix=None,
266  
-                 initial=None, error_class=ErrorList, label_suffix=':'):
267  
-        self.instance = instance
  265
+    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
  266
+                 initial=None, error_class=ErrorList, label_suffix=':', instance=None):
268 267
         opts = self._meta
269  
-        object_data = model_to_dict(instance, opts.fields, opts.exclude)
  268
+        if instance is None:
  269
+            # if we didn't get an instance, instantiate a new one
  270
+            self.instance = opts.model()
  271
+            object_data = {}
  272
+        else:
  273
+            self.instance = instance
  274
+            object_data = model_to_dict(instance, opts.fields, opts.exclude)
270 275
         # if initial was provided, it should override the values from instance
271 276
         if initial is not None:
272 277
             object_data.update(initial)
27  docs/modelforms.txt
@@ -24,12 +24,11 @@ For example::
24 24
     ...         model = Article
25 25
 
26 26
     # Creating a form to add an article.
27  
-    >>> article = Article()
28  
-    >>> form = ArticleForm(article)
  27
+    >>> form = ArticleForm()
29 28
 
30 29
     # Creating a form to change an existing article.
31 30
     >>> article = Article.objects.get(pk=1)
32  
-    >>> form = ArticleForm(article)
  31
+    >>> form = ArticleForm(instance=article)
33 32
 
34 33
 Field types
35 34
 -----------
@@ -166,18 +165,23 @@ we'll discuss in a moment.)::
166 165
 The ``save()`` method
167 166
 ---------------------
168 167
 
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::
  168
+Every form produced by ``ModelForm`` also has a ``save()``
  169
+method. This method creates and saves a database object from the data
  170
+bound to the form. A subclass of ``ModelForm`` can accept an existing
  171
+model instance as the keyword argument ``instance``; if this is
  172
+supplied, ``save()`` will update that instance. If it's not supplied,
  173
+``save()`` will create a new instance of the specified model::
173 174
 
174 175
     # Create a form instance from POST data.
175  
-    >>> a = Article()
176  
-    >>> f = ArticleForm(a, request.POST)
  176
+    >>> f = ArticleForm(request.POST)
177 177
 
178 178
     # Save a new Article object from the form's data.
179 179
     >>> new_article = f.save()
180 180
 
  181
+    # Create a form to edit an existing Article.
  182
+    >>> a = Article.objects.get(pk=1)
  183
+    >>> f = ArticleForm(instance=a)
  184
+
181 185
 Note that ``save()`` will raise a ``ValueError`` if the data in the form
182 186
 doesn't validate -- i.e., ``if form.errors``.
183 187
 
@@ -201,8 +205,7 @@ you've manually saved the instance produced by the form, you can invoke
201 205
 ``save_m2m()`` to save the many-to-many form data. For example::
202 206
 
203 207
     # Create a form instance with POST data.
204  
-    >>> a = Author()
205  
-    >>> f = AuthorForm(a, request.POST)
  208
+    >>> f = AuthorForm(request.POST)
206 209
 
207 210
     # Create, but don't save the new author instance.
208 211
     >>> new_author = f.save(commit=False)
@@ -277,7 +280,7 @@ model fields:
277 280
     manually set anyextra required fields::
278 281
     
279 282
         instance = Instance(required_field='value')
280  
-        form = InstanceForm(instance, request.POST)
  283
+        form = InstanceForm(request.POST, instance=instance)
281 284
         new_instance = form.save()
282 285
 
283 286
         instance = form.save(commit=False)
48  tests/modeltests/model_forms/models.py
@@ -167,7 +167,7 @@ def __unicode__(self):
167 167
 >>> class CategoryForm(ModelForm):
168 168
 ...     class Meta:
169 169
 ...         model = Category
170  
->>> f = CategoryForm(Category())
  170
+>>> f = CategoryForm()
171 171
 >>> print f
172 172
 <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>
173 173
 <tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr>
@@ -179,13 +179,13 @@ def __unicode__(self):
179 179
 >>> print f['name']
180 180
 <input id="id_name" type="text" name="name" maxlength="20" />
181 181
 
182  
->>> f = CategoryForm(Category(), auto_id=False)
  182
+>>> f = CategoryForm(auto_id=False)
183 183
 >>> print f.as_ul()
184 184
 <li>Name: <input type="text" name="name" maxlength="20" /></li>
185 185
 <li>Slug: <input type="text" name="slug" maxlength="20" /></li>
186 186
 <li>The URL: <input type="text" name="url" maxlength="40" /></li>
187 187
 
188  
->>> f = CategoryForm(Category(), {'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'})
  188
+>>> f = CategoryForm({'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'})
189 189
 >>> f.is_valid()
190 190
 True
191 191
 >>> f.cleaned_data
@@ -196,7 +196,7 @@ def __unicode__(self):
196 196
 >>> Category.objects.all()
197 197
 [<Category: Entertainment>]
198 198
 
199  
->>> f = CategoryForm(Category(), {'name': "It's a test", 'slug': 'its-test', 'url': 'test'})
  199
+>>> f = CategoryForm({'name': "It's a test", 'slug': 'its-test', 'url': 'test'})
200 200
 >>> f.is_valid()
201 201
 True
202 202
 >>> f.cleaned_data
@@ -210,7 +210,7 @@ def __unicode__(self):
210 210
 If you call save() with commit=False, then it will return an object that
211 211
 hasn't yet been saved to the database. In this case, it's up to you to call
212 212
 save() on the resulting model instance.
213  
->>> f = CategoryForm(Category(), {'name': 'Third test', 'slug': 'third-test', 'url': 'third'})
  213
+>>> f = CategoryForm({'name': 'Third test', 'slug': 'third-test', 'url': 'third'})
214 214
 >>> f.is_valid()
215 215
 True
216 216
 >>> f.cleaned_data
@@ -225,7 +225,7 @@ def __unicode__(self):
225 225
 [<Category: Entertainment>, <Category: It's a test>, <Category: Third test>]
226 226
 
227 227
 If you call save() with invalid data, you'll get a ValueError.
228  
->>> f = CategoryForm(Category(), {'name': '', 'slug': '', 'url': 'foo'})
  228
+>>> f = CategoryForm({'name': '', 'slug': '', 'url': 'foo'})
229 229
 >>> f.errors
230 230
 {'name': [u'This field is required.'], 'slug': [u'This field is required.']}
231 231
 >>> f.cleaned_data
@@ -236,7 +236,7 @@ def __unicode__(self):
236 236
 Traceback (most recent call last):
237 237
 ...
238 238
 ValueError: The Category could not be created because the data didn't validate.
239  
->>> f = CategoryForm(Category(), {'name': '', 'slug': '', 'url': 'foo'})
  239
+>>> f = CategoryForm({'name': '', 'slug': '', 'url': 'foo'})
240 240
 >>> f.save()
241 241
 Traceback (most recent call last):
242 242
 ...
@@ -253,7 +253,7 @@ def __unicode__(self):
253 253
 >>> class ArticleForm(ModelForm):
254 254
 ...     class Meta:
255 255
 ...         model = Article
256  
->>> f = ArticleForm(Article(), auto_id=False)
  256
+>>> f = ArticleForm(auto_id=False)
257 257
 >>> print f
258 258
 <tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
259 259
 <tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr>
@@ -286,7 +286,7 @@ def __unicode__(self):
286 286
 ...     class Meta:
287 287
 ...         model = Article
288 288
 ...         fields = ('headline','pub_date')
289  
->>> f = PartialArticleForm(Article(), auto_id=False)
  289
+>>> f = PartialArticleForm(auto_id=False)
290 290
 >>> print f
291 291
 <tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
292 292
 <tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>
@@ -298,7 +298,7 @@ def __unicode__(self):
298 298
 >>> class RoykoForm(ModelForm):
299 299
 ...     class Meta:
300 300
 ...         model = Writer
301  
->>> f = RoykoForm(w, auto_id=False)
  301
+>>> f = RoykoForm(auto_id=False, instance=w)
302 302
 >>> print f
303 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 304
 
@@ -309,7 +309,7 @@ def __unicode__(self):
309 309
 >>> class TestArticleForm(ModelForm):
310 310
 ...     class Meta:
311 311
 ...         model = Article
312  
->>> f = TestArticleForm(art, auto_id=False)
  312
+>>> f = TestArticleForm(auto_id=False, instance=art)
313 313
 >>> print f.as_ul()
314 314
 <li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /></li>
315 315
 <li>Slug: <input type="text" name="slug" value="test-article" maxlength="50" /></li>
@@ -331,7 +331,7 @@ def __unicode__(self):
331 331
 <option value="2">It&#39;s a test</option>
332 332
 <option value="3">Third test</option>
333 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.'})
  334
+>>> f = TestArticleForm({'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': u'1', 'article': 'Hello.'}, instance=art)
335 335
 >>> f.is_valid()
336 336
 True
337 337
 >>> test_art = f.save()
@@ -347,7 +347,7 @@ def __unicode__(self):
347 347
 ...     class Meta:
348 348
 ...         model = Article
349 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)
  350
+>>> f = PartialArticleForm({'headline': u'New headline', 'slug': 'new-headline', 'pub_date': u'1988-01-04'}, auto_id=False, instance=art)
351 351
 >>> print f.as_ul()
352 352
 <li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
353 353
 <li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li>
@@ -370,7 +370,7 @@ def __unicode__(self):
370 370
 >>> class TestArticleForm(ModelForm):
371 371
 ...     class Meta:
372 372
 ...         model = Article
373  
->>> f = TestArticleForm(new_art, auto_id=False)
  373
+>>> f = TestArticleForm(auto_id=False, instance=new_art)
374 374
 >>> print f.as_ul()
375 375
 <li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
376 376
 <li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li>
@@ -393,8 +393,8 @@ def __unicode__(self):
393 393
 <option value="3">Third test</option>
394 394
 </select>  Hold down "Control", or "Command" on a Mac, to select more than one.</li>
395 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']})
  396
+>>> f = TestArticleForm({'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']}, instance=new_art)
398 398
 >>> new_art = f.save()
399 399
 >>> new_art.id
400 400
 1
@@ -403,8 +403,8 @@ def __unicode__(self):
403 403
 [<Category: Entertainment>, <Category: It's a test>]
404 404
 
405 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.'})
  406
+>>> f = TestArticleForm({'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04',
  407
+...     'writer': u'1', 'article': u'Hello.'}, instance=new_art)
408 408
 >>> new_art = f.save()
409 409
 >>> new_art.id
410 410
 1
@@ -416,7 +416,7 @@ def __unicode__(self):
416 416
 >>> class ArticleForm(ModelForm):
417 417
 ...     class Meta:
418 418
 ...         model = Article
419  
->>> f = ArticleForm(Article(), {'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01',
  419
+>>> f = ArticleForm({'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01',
420 420
 ...     'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']})
421 421
 >>> new_art = f.save()
422 422
 >>> new_art.id
@@ -429,7 +429,7 @@ def __unicode__(self):
429 429
 >>> class ArticleForm(ModelForm):
430 430
 ...     class Meta:
431 431
 ...         model = Article
432  
->>> f = ArticleForm(Article(), {'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01',
  432
+>>> f = ArticleForm({'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01',
433 433
 ...     'writer': u'1', 'article': u'Test.'})
434 434
 >>> new_art = f.save()
435 435
 >>> new_art.id
@@ -443,7 +443,7 @@ def __unicode__(self):
443 443
 >>> class ArticleForm(ModelForm):
444 444
 ...     class Meta:
445 445
 ...         model = Article
446  
->>> f = ArticleForm(Article(), {'headline': u'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': u'1967-11-01',
  446
+>>> f = ArticleForm({'headline': u'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': u'1967-11-01',
447 447
 ...     'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']})
448 448
 >>> new_art = f.save(commit=False)
449 449
 
@@ -474,7 +474,7 @@ def __unicode__(self):
474 474
 <Category: Third test>
475 475
 >>> cat.id
476 476
 3
477  
->>> form = ShortCategory(cat, {'name': 'Third', 'slug': 'third', 'url': '3rd'})
  477
+>>> form = ShortCategory({'name': 'Third', 'slug': 'third', 'url': '3rd'}, instance=cat)
478 478
 >>> form.save()
479 479
 <Category: Third>
480 480
 >>> Category.objects.get(id=3)
@@ -486,7 +486,7 @@ def __unicode__(self):
486 486
 >>> class ArticleForm(ModelForm):
487 487
 ...     class Meta:
488 488
 ...         model = Article
489  
->>> f = ArticleForm(Article(), auto_id=False)
  489
+>>> f = ArticleForm(auto_id=False)
490 490
 >>> print f.as_ul()
491 491
 <li>Headline: <input type="text" name="headline" maxlength="50" /></li>
492 492
 <li>Slug: <input type="text" name="slug" maxlength="50" /></li>
@@ -690,7 +690,7 @@ def __unicode__(self):
690 690
 >>> class PhoneNumberForm(ModelForm):
691 691
 ...     class Meta:
692 692
 ...         model = PhoneNumber
693  
->>> f = PhoneNumberForm(PhoneNumber(), {'phone': '(312) 555-1212', 'description': 'Assistance'})
  693
+>>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'})
694 694
 >>> f.is_valid()
695 695
 True
696 696
 >>> f.cleaned_data

0 notes on commit e415eff

Please sign in to comment.
Something went wrong with that request. Please try again.