Author: brosner
Date: 2008-08-24 22:51:25 -0500 (Sun, 24 Aug 2008)
New Revision: 8528

Modified:
   django/trunk/django/db/models/fields/__init__.py
   django/trunk/django/forms/models.py
   django/trunk/tests/modeltests/model_forms/models.py
   django/trunk/tests/modeltests/model_formsets/models.py
Log:
Fixed #7888 -- Handle model inheritance with model formsets correctly. Thanks 
bpeschier for the report.

Modified: django/trunk/django/db/models/fields/__init__.py
===================================================================
--- django/trunk/django/db/models/fields/__init__.py    2008-08-25 03:26:37 UTC 
(rev 8527)
+++ django/trunk/django/db/models/fields/__init__.py    2008-08-25 03:51:25 UTC 
(rev 8528)
@@ -97,6 +97,7 @@
         self.help_text = help_text
         self.db_column = db_column
         self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE
+        self.auto_created = auto_created
 
         # Set db_index to True if the field has a relationship and doesn't 
explicitly set db_index.
         self.db_index = db_index

Modified: django/trunk/django/forms/models.py
===================================================================
--- django/trunk/django/forms/models.py 2008-08-25 03:26:37 UTC (rev 8527)
+++ django/trunk/django/forms/models.py 2008-08-25 03:51:25 UTC (rev 8528)
@@ -96,7 +96,7 @@
     the ``fields`` argument.
     """
     # avoid a circular import
-    from django.db.models.fields.related import ManyToManyField
+    from django.db.models.fields.related import ManyToManyField, OneToOneField
     opts = instance._meta
     data = {}
     for f in opts.fields + opts.many_to_many:
@@ -115,6 +115,8 @@
             else:
                 # MultipleChoiceWidget needs a list of pks, not object 
instances.
                 data[f.name] = [obj.pk for obj in 
f.value_from_object(instance)]
+        elif isinstance(f, OneToOneField):
+            data[f.attname] = f.value_from_object(instance)
         else:
             data[f.name] = f.value_from_object(instance)
     return data
@@ -317,7 +319,7 @@
 
     def add_fields(self, form, index):
         """Add a hidden field for the object's primary key."""
-        if self.model._meta.has_auto_field:
+        if self.model._meta.pk.auto_created:
             self._pk_field_name = self.model._meta.pk.attname
             form.fields[self._pk_field_name] = IntegerField(required=False, 
widget=HiddenInput)
         super(BaseModelFormSet, self).add_fields(form, index)

Modified: django/trunk/tests/modeltests/model_forms/models.py
===================================================================
--- django/trunk/tests/modeltests/model_forms/models.py 2008-08-25 03:26:37 UTC 
(rev 8527)
+++ django/trunk/tests/modeltests/model_forms/models.py 2008-08-25 03:51:25 UTC 
(rev 8528)
@@ -13,6 +13,12 @@
 from django.db import models
 from django.core.files.storage import FileSystemStorage
 
+# Python 2.3 doesn't have sorted()
+try:
+    sorted
+except NameError:
+    from django.utils.itercompat import sorted
+
 temp_storage = FileSystemStorage(tempfile.gettempdir())
 
 ARTICLE_STATUS = (
@@ -60,6 +66,9 @@
 class ImprovedArticleWithParentLink(models.Model):
     article = models.OneToOneField(Article, parent_link=True)
 
+class BetterWriter(Writer):
+    pass
+
 class PhoneNumber(models.Model):
     phone = models.PhoneNumberField()
     description = models.CharField(max_length=20)
@@ -91,7 +100,7 @@
 
 __test__ = {'API_TESTS': """
 >>> from django import forms
->>> from django.forms.models import ModelForm
+>>> from django.forms.models import ModelForm, model_to_dict
 >>> from django.core.files.uploadedfile import SimpleUploadedFile
 
 The bare bones, absolutely nothing custom, basic case.
@@ -793,6 +802,11 @@
 >>> ImprovedArticleWithParentLinkForm.base_fields.keys()
 []
 
+>>> bw = BetterWriter(name=u'Joe Better')
+>>> bw.save()
+>>> sorted(model_to_dict(bw).keys())
+['id', 'name', 'writer_ptr_id']
+
 # PhoneNumberField ############################################################
 
 >>> class PhoneNumberForm(ModelForm):

Modified: django/trunk/tests/modeltests/model_formsets/models.py
===================================================================
--- django/trunk/tests/modeltests/model_formsets/models.py      2008-08-25 
03:26:37 UTC (rev 8527)
+++ django/trunk/tests/modeltests/model_formsets/models.py      2008-08-25 
03:51:25 UTC (rev 8528)
@@ -14,6 +14,9 @@
     def __unicode__(self):
         return self.name
 
+class BetterAuthor(Author):
+    write_speed = models.IntegerField()
+
 class Book(models.Model):
     author = models.ForeignKey(Author)
     title = models.CharField(max_length=100)
@@ -229,7 +232,54 @@
 >>> [sorted(x.items()) for x in formset.initial]
 [[('id', 1), ('name', u'Charles Baudelaire')], [('id', 3), ('name', u'Paul 
Verlaine')], [('id', 2), ('name', u'Walt Whitman')]]
 
+# Model inheritance in model formsets ########################################
 
+>>> BetterAuthorFormSet = modelformset_factory(BetterAuthor)
+>>> formset = BetterAuthorFormSet()
+>>> for form in formset.forms:
+...     print form.as_p()
+<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" 
type="text" name="form-0-name" maxlength="100" /></p>
+<p><label for="id_form-0-write_speed">Write speed:</label> <input type="text" 
name="form-0-write_speed" id="id_form-0-write_speed" /><input type="hidden" 
name="form-0-author_ptr_id" id="id_form-0-author_ptr_id" /></p>
+
+>>> data = {
+...     'form-TOTAL_FORMS': '1', # the number of forms rendered
+...     'form-INITIAL_FORMS': '0', # the number of forms with initial data
+...     'form-0-author_ptr_id': '',
+...     'form-0-name': 'Ernest Hemingway',
+...     'form-0-write_speed': '10',
+... }
+
+>>> formset = BetterAuthorFormSet(data)
+>>> formset.is_valid()
+True
+>>> formset.save()
+[<BetterAuthor: Ernest Hemingway>]
+
+>>> formset = BetterAuthorFormSet()
+>>> for form in formset.forms:
+...     print form.as_p()
+<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" 
type="text" name="form-0-name" value="Ernest Hemingway" maxlength="100" /></p>
+<p><label for="id_form-0-write_speed">Write speed:</label> <input type="text" 
name="form-0-write_speed" value="10" id="id_form-0-write_speed" /><input 
type="hidden" name="form-0-author_ptr_id" value="4" 
id="id_form-0-author_ptr_id" /></p>
+<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" 
type="text" name="form-1-name" maxlength="100" /></p>
+<p><label for="id_form-1-write_speed">Write speed:</label> <input type="text" 
name="form-1-write_speed" id="id_form-1-write_speed" /><input type="hidden" 
name="form-1-author_ptr_id" id="id_form-1-author_ptr_id" /></p>
+
+>>> data = {
+...     'form-TOTAL_FORMS': '2', # the number of forms rendered
+...     'form-INITIAL_FORMS': '1', # the number of forms with initial data
+...     'form-0-author_ptr_id': '4',
+...     'form-0-name': 'Ernest Hemingway',
+...     'form-0-write_speed': '10',
+...     'form-1-author_ptr_id': '',
+...     'form-1-name': '',
+...     'form-1-write_speed': '',
+... }
+
+>>> formset = BetterAuthorFormSet(data)
+>>> formset.is_valid()
+True
+>>> formset.save()
+[]
+
 # Inline Formsets ############################################################
 
 We can also create a formset that is tied to a parent model. This is how the


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to