Ticket #6162: modelform-init.diff

File modelform-init.diff, 13.2 KB (added by James Bennett, 16 years ago)

Patch which "fixes" ModelForm.__init__()

  • django/newforms/models.py

     
    262262        return type.__new__(cls, name, bases, attrs)
    263263
    264264class 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):
    268267        opts = self._meta
    269         object_data = model_to_dict(instance, opts.fields, opts.exclude)
     268        if instance is None:
     269           self.instance = opts.model()
     270           object_data = {}
     271        else:
     272            self.instance = instance
     273            object_data = model_to_dict(instance, opts.fields, opts.exclude)
    270274        # if initial was provided, it should override the values from instance
    271275        if initial is not None:
    272276            object_data.update(initial)
  • tests/modeltests/model_forms/models.py

     
    156156ImproperlyConfigured: BadForm's base classes define more than one model.
    157157
    158158
    159 # Old form_for_x tests #######################################################
     159# Test valid ModelForms #######################################################
    160160
    161161>>> from django.newforms import ModelForm, CharField
    162162>>> import datetime
     
    167167>>> class CategoryForm(ModelForm):
    168168...     class Meta:
    169169...         model = Category
    170 >>> f = CategoryForm(Category())
     170>>> f = CategoryForm()
    171171>>> print f
    172172<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>
    173173<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr>
     
    179179>>> print f['name']
    180180<input id="id_name" type="text" name="name" maxlength="20" />
    181181
    182 >>> f = CategoryForm(Category(), auto_id=False)
     182>>> f = CategoryForm(auto_id=False)
    183183>>> print f.as_ul()
    184184<li>Name: <input type="text" name="name" maxlength="20" /></li>
    185185<li>Slug: <input type="text" name="slug" maxlength="20" /></li>
    186186<li>The URL: <input type="text" name="url" maxlength="40" /></li>
    187187
    188 >>> f = CategoryForm(Category(), {'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'})
     188>>> f = CategoryForm({'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'})
    189189>>> f.is_valid()
    190190True
    191191>>> f.cleaned_data
     
    196196>>> Category.objects.all()
    197197[<Category: Entertainment>]
    198198
    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'})
    200200>>> f.is_valid()
    201201True
    202202>>> f.cleaned_data
     
    210210If you call save() with commit=False, then it will return an object that
    211211hasn't yet been saved to the database. In this case, it's up to you to call
    212212save() 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'})
    214214>>> f.is_valid()
    215215True
    216216>>> f.cleaned_data
     
    225225[<Category: Entertainment>, <Category: It's a test>, <Category: Third test>]
    226226
    227227If 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'})
    229229>>> f.errors
    230230{'name': [u'This field is required.'], 'slug': [u'This field is required.']}
    231231>>> f.cleaned_data
     
    236236Traceback (most recent call last):
    237237...
    238238ValueError: 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'})
    240240>>> f.save()
    241241Traceback (most recent call last):
    242242...
     
    253253>>> class ArticleForm(ModelForm):
    254254...     class Meta:
    255255...         model = Article
    256 >>> f = ArticleForm(Article(), auto_id=False)
     256>>> f = ArticleForm(auto_id=False)
    257257>>> print f
    258258<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
    259259<tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr>
     
    286286...     class Meta:
    287287...         model = Article
    288288...         fields = ('headline','pub_date')
    289 >>> f = PartialArticleForm(Article(), auto_id=False)
     289>>> f = PartialArticleForm(auto_id=False)
    290290>>> print f
    291291<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
    292292<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>
     
    298298>>> class RoykoForm(ModelForm):
    299299...     class Meta:
    300300...         model = Writer
    301 >>> f = RoykoForm(w, auto_id=False)
     301>>> f = RoykoForm(auto_id=False, instance=w)
    302302>>> print f
    303303<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br />Use both first and last names.</td></tr>
    304304
     
    309309>>> class TestArticleForm(ModelForm):
    310310...     class Meta:
    311311...         model = Article
    312 >>> f = TestArticleForm(art, auto_id=False)
     312>>> f = TestArticleForm(instance=art, auto_id=False)
    313313>>> print f.as_ul()
    314314<li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /></li>
    315315<li>Slug: <input type="text" name="slug" value="test-article" maxlength="50" /></li>
     
    331331<option value="2">It&#39;s a test</option>
    332332<option value="3">Third test</option>
    333333</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)
    335335>>> f.is_valid()
    336336True
    337337>>> test_art = f.save()
     
    347347...     class Meta:
    348348...         model = Article
    349349...         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)
    351351>>> print f.as_ul()
    352352<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
    353353<li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li>
     
    370370>>> class TestArticleForm(ModelForm):
    371371...     class Meta:
    372372...         model = Article
    373 >>> f = TestArticleForm(new_art, auto_id=False)
     373>>> f = TestArticleForm(auto_id=False, instance=new_art)
    374374>>> print f.as_ul()
    375375<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
    376376<li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li>
     
    393393<option value="3">Third test</option>
    394394</select>  Hold down "Control", or "Command" on a Mac, to select more than one.</li>
    395395
    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)
    398398>>> new_art = f.save()
    399399>>> new_art.id
    4004001
     
    403403[<Category: Entertainment>, <Category: It's a test>]
    404404
    405405Now, 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)
    408408>>> new_art = f.save()
    409409>>> new_art.id
    4104101
     
    416416>>> class ArticleForm(ModelForm):
    417417...     class Meta:
    418418...         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',
    420420...     'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']})
    421421>>> new_art = f.save()
    422422>>> new_art.id
     
    429429>>> class ArticleForm(ModelForm):
    430430...     class Meta:
    431431...         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',
    433433...     'writer': u'1', 'article': u'Test.'})
    434434>>> new_art = f.save()
    435435>>> new_art.id
     
    443443>>> class ArticleForm(ModelForm):
    444444...     class Meta:
    445445...         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',
    447447...     'writer': u'1', 'article': u'Test.', 'categories': [u'1', u'2']})
    448448>>> new_art = f.save(commit=False)
    449449
     
    474474<Category: Third test>
    475475>>> cat.id
    4764763
    477 >>> form = ShortCategory(cat, {'name': 'Third', 'slug': 'third', 'url': '3rd'})
     477>>> form = ShortCategory({'name': 'Third', 'slug': 'third', 'url': '3rd'}, instance=cat)
    478478>>> form.save()
    479479<Category: Third>
    480480>>> Category.objects.get(id=3)
     
    486486>>> class ArticleForm(ModelForm):
    487487...     class Meta:
    488488...         model = Article
    489 >>> f = ArticleForm(Article(), auto_id=False)
     489>>> f = ArticleForm(auto_id=False)
    490490>>> print f.as_ul()
    491491<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
    492492<li>Slug: <input type="text" name="slug" maxlength="50" /></li>
     
    690690>>> class PhoneNumberForm(ModelForm):
    691691...     class Meta:
    692692...         model = PhoneNumber
    693 >>> f = PhoneNumberForm(PhoneNumber(), {'phone': '(312) 555-1212', 'description': 'Assistance'})
     693>>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'})
    694694>>> f.is_valid()
    695695True
    696696>>> f.cleaned_data
  • docs/modelforms.txt

     
    2424    ...         model = Article
    2525
    2626    # Creating a form to add an article.
    27     >>> article = Article()
    28     >>> form = ArticleForm(article)
     27    >>> form = ArticleForm()
    2928
    3029    # Creating a form to change an existing article.
    3130    >>> article = Article.objects.get(pk=1)
    32     >>> form = ArticleForm(article)
     31    >>> form = ArticleForm(instance=article)
    3332
    3433Field types
    3534-----------
     
    166165The ``save()`` method
    167166---------------------
    168167
    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::
     168Every form produced by ``ModelForm`` also has a ``save()``
     169method. This method creates and saves a database object from the data
     170bound to the form. A subclass of ``ModelForm`` can accept an existing
     171model instance as the keyword argument ``instance``; if this is
     172supplied, ``save()`` will update that instance. If it's not supplied,
     173``save()`` will create a new instance of the specified model::
    173174
    174175    # Create a form instance from POST data.
    175     >>> a = Article()
    176     >>> f = ArticleForm(a, request.POST)
     176    >>> f = ArticleForm(request.POST)
    177177
    178178    # Save a new Article object from the form's data.
    179179    >>> new_article = f.save()
    180180
     181    # Create a form to edit an existing Article.
     182    >>> a = Article.objects.get(pk=1)
     183    >>> f = ArticleForm(instance=a)
     184
    181185Note that ``save()`` will raise a ``ValueError`` if the data in the form
    182186doesn't validate -- i.e., ``if form.errors``.
    183187
     
    201205``save_m2m()`` to save the many-to-many form data. For example::
    202206
    203207    # Create a form instance with POST data.
    204     >>> a = Author()
    205     >>> f = AuthorForm(a, request.POST)
     208    >>> f = AuthorForm(request.POST)
    206209
    207210    # Create, but don't save the new author instance.
    208211    >>> new_author = f.save(commit=False)
     
    222225For example::
    223226
    224227    # Create a form instance with POST data.
    225     >>> a = Author()
    226     >>> f = AuthorForm(a, request.POST)
     228    >>> f = AuthorForm(request.POST)
    227229
    228230    # Create and save the new author instance. There's no need to do anything else.
    229231    >>> new_author = f.save()
     
    277279    manually set anyextra required fields::
    278280   
    279281        instance = Instance(required_field='value')
    280         form = InstanceForm(instance, request.POST)
     282        form = InstanceForm(request.POST, instance=instance)
    281283        new_instance = form.save()
    282284
    283285        instance = form.save(commit=False)
Back to Top