newforms: Got form_for_instance() to select initial ManyToManyField values properly

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4261 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-12-30 00:12:02 +00:00
parent 0919920bc0
commit b9fdf9abb8
2 changed files with 31 additions and 2 deletions

View File

@ -726,6 +726,10 @@ class ManyToManyField(RelatedField, Field):
return getattr(obj, self.attname).all() return getattr(obj, self.attname).all()
def formfield(self, initial=None): def formfield(self, initial=None):
# If initial is passed in, it's a list of related objects, but the
# MultipleChoiceField takes a list of IDs.
if initial is not None:
initial = [i._get_pk_val() for i in initial]
return forms.MultipleChoiceField(choices=self.get_choices_default(), required=not self.blank, label=capfirst(self.verbose_name), initial=initial) return forms.MultipleChoiceField(choices=self.get_choices_default(), required=not self.blank, label=capfirst(self.verbose_name), initial=initial)
class ManyToOneRel(object): class ManyToOneRel(object):

View File

@ -28,7 +28,7 @@ class Writer(models.Model):
class Article(models.Model): class Article(models.Model):
headline = models.CharField(maxlength=50) headline = models.CharField(maxlength=50)
pub_date = models.DateTimeField() pub_date = models.DateField()
writer = models.ForeignKey(Writer) writer = models.ForeignKey(Writer)
categories = models.ManyToManyField(Category, blank=True) categories = models.ManyToManyField(Category, blank=True)
@ -80,6 +80,8 @@ __test__ = {'API_TESTS': """
>>> Category.objects.all() >>> Category.objects.all()
[<Category: Entertainment>, <Category: It's a test>] [<Category: Entertainment>, <Category: It's a test>]
If you call create() with save=False, then it will return an object that hasn't
yet been saved. In this case, it's up to you to save it.
>>> f = CategoryForm({'name': 'Third test', 'url': 'third'}) >>> f = CategoryForm({'name': 'Third test', 'url': 'third'})
>>> f.errors >>> f.errors
{} {}
@ -94,6 +96,7 @@ __test__ = {'API_TESTS': """
>>> Category.objects.all() >>> Category.objects.all()
[<Category: Entertainment>, <Category: It's a test>, <Category: Third test>] [<Category: Entertainment>, <Category: It's a test>, <Category: Third test>]
If you call create() with invalid data, you'll get a ValueError.
>>> f = CategoryForm({'name': '', 'url': 'foo'}) >>> f = CategoryForm({'name': '', 'url': 'foo'})
>>> f.errors >>> f.errors
{'name': [u'This field is required.']} {'name': [u'This field is required.']}
@ -102,7 +105,6 @@ __test__ = {'API_TESTS': """
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: The Category could not be created because the data didn't validate. ValueError: The Category could not be created because the data didn't validate.
>>> f = CategoryForm({'name': '', 'url': 'foo'}) >>> f = CategoryForm({'name': '', 'url': 'foo'})
>>> f.create() >>> f.create()
Traceback (most recent call last): Traceback (most recent call last):
@ -181,4 +183,27 @@ True
>>> new_art = Article.objects.get(id=1) >>> new_art = Article.objects.get(id=1)
>>> new_art.headline >>> new_art.headline
'New headline' 'New headline'
Add some categories and test the many-to-many form output.
>>> new_art.categories.all()
[]
>>> new_art.categories.add(Category.objects.get(name='Entertainment'))
>>> new_art.categories.all()
[<Category: Entertainment>]
>>> TestArticleForm = form_for_instance(new_art)
>>> f = TestArticleForm(auto_id=False)
>>> print f.as_ul()
<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li>
<li>Writer: <select name="writer">
<option value="">---------</option>
<option value="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option>
</select></li>
<li>Categories: <select multiple="multiple" name="categories">
<option value="1" selected="selected">Entertainment</option>
<option value="2">It&#39;s a test</option>
<option value="3">Third test</option>
</select></li>
"""} """}