Code

Ticket #8241: onetoone_admin.8541.diff

File onetoone_admin.8541.diff, 3.2 KB (added by semenov, 6 years ago)
Line 
1Index: django/forms/models.py
2===================================================================
3--- django/forms/models.py      (revision 8541)
4+++ django/forms/models.py      (working copy)
5@@ -28,14 +28,14 @@
6     If commit=True, then the changes to ``instance`` will be saved to the
7     database. Returns ``instance``.
8     """
9-    from django.db import models
10+    from django.db.models import AutoField, OneToOneField
11     opts = instance._meta
12     if form.errors:
13         raise ValueError("The %s could not be %s because the data didn't"
14                          " validate." % (opts.object_name, fail_message))
15     cleaned_data = form.cleaned_data
16     for f in opts.fields:
17-        if not f.editable or isinstance(f, models.AutoField) \
18+        if not f.editable or isinstance(f, (AutoField, OneToOneField)) \
19                 or not f.name in cleaned_data:
20             continue
21         if fields and f.name not in fields:
22@@ -96,7 +96,7 @@
23     the ``fields`` argument.
24     """
25     # avoid a circular import
26-    from django.db.models.fields.related import ManyToManyField, OneToOneField
27+    from django.db.models.fields.related import ManyToManyField
28     opts = instance._meta
29     data = {}
30     for f in opts.fields + opts.many_to_many:
31@@ -107,7 +107,7 @@
32         if exclude and f.name in exclude:
33             continue
34         if isinstance(f, ManyToManyField):
35-            # If the object doesn't have a primry key yet, just use an empty
36+            # If the object doesn't have a primary key yet, just use an empty
37             # list for its m2m fields. Calling f.value_from_object will raise
38             # an exception.
39             if instance.pk is None:
40@@ -115,8 +115,6 @@
41             else:
42                 # MultipleChoiceWidget needs a list of pks, not object instances.
43                 data[f.name] = [obj.pk for obj in f.value_from_object(instance)]
44-        elif isinstance(f, OneToOneField):
45-            data[f.attname] = f.value_from_object(instance)
46         else:
47             data[f.name] = f.value_from_object(instance)
48     return data
49@@ -291,7 +289,7 @@
50             existing_objects[obj.pk] = obj
51         saved_instances = []
52         for form in self.initial_forms:
53-            obj = existing_objects[form.cleaned_data[self.model._meta.pk.attname]]
54+            obj = existing_objects[form.cleaned_data[self._pk_field_name]]
55             if self.can_delete and form.cleaned_data[DELETION_FIELD_NAME]:
56                 self.deleted_objects.append(obj)
57                 obj.delete()
58@@ -319,8 +317,12 @@
59 
60     def add_fields(self, form, index):
61         """Add a hidden field for the object's primary key."""
62-        if self.model._meta.pk.auto_created:
63-            self._pk_field_name = self.model._meta.pk.attname
64+        from django.db.models import OneToOneField
65+        pk = self.model._meta.pk
66+        while isinstance(pk, OneToOneField):
67+            pk = pk.rel.to._meta.pk # Drill down until we find a "real" pk
68+        if pk.auto_created:
69+            self._pk_field_name = self.model._meta.pk.name
70             form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput)
71         super(BaseModelFormSet, self).add_fields(form, index)
72