Ticket #8241: onetoone_admin.8541.diff

File onetoone_admin.8541.diff, 3.2 KB (added by semenov, 7 years ago)
  • django/forms/models.py

     
    2828    If commit=True, then the changes to ``instance`` will be saved to the
    2929    database. Returns ``instance``.
    3030    """
    31     from django.db import models
     31    from django.db.models import AutoField, OneToOneField
    3232    opts = instance._meta
    3333    if form.errors:
    3434        raise ValueError("The %s could not be %s because the data didn't"
    3535                         " validate." % (opts.object_name, fail_message))
    3636    cleaned_data = form.cleaned_data
    3737    for f in opts.fields:
    38         if not f.editable or isinstance(f, models.AutoField) \
     38        if not f.editable or isinstance(f, (AutoField, OneToOneField)) \
    3939                or not f.name in cleaned_data:
    4040            continue
    4141        if fields and f.name not in fields:
     
    9696    the ``fields`` argument.
    9797    """
    9898    # avoid a circular import
    99     from django.db.models.fields.related import ManyToManyField, OneToOneField
     99    from django.db.models.fields.related import ManyToManyField
    100100    opts = instance._meta
    101101    data = {}
    102102    for f in opts.fields + opts.many_to_many:
     
    107107        if exclude and f.name in exclude:
    108108            continue
    109109        if isinstance(f, ManyToManyField):
    110             # If the object doesn't have a primry key yet, just use an empty
     110            # If the object doesn't have a primary key yet, just use an empty
    111111            # list for its m2m fields. Calling f.value_from_object will raise
    112112            # an exception.
    113113            if instance.pk is None:
     
    115115            else:
    116116                # MultipleChoiceWidget needs a list of pks, not object instances.
    117117                data[f.name] = [obj.pk for obj in f.value_from_object(instance)]
    118         elif isinstance(f, OneToOneField):
    119             data[f.attname] = f.value_from_object(instance)
    120118        else:
    121119            data[f.name] = f.value_from_object(instance)
    122120    return data
     
    291289            existing_objects[obj.pk] = obj
    292290        saved_instances = []
    293291        for form in self.initial_forms:
    294             obj = existing_objects[form.cleaned_data[self.model._meta.pk.attname]]
     292            obj = existing_objects[form.cleaned_data[self._pk_field_name]]
    295293            if self.can_delete and form.cleaned_data[DELETION_FIELD_NAME]:
    296294                self.deleted_objects.append(obj)
    297295                obj.delete()
     
    319317
    320318    def add_fields(self, form, index):
    321319        """Add a hidden field for the object's primary key."""
    322         if self.model._meta.pk.auto_created:
    323             self._pk_field_name = self.model._meta.pk.attname
     320        from django.db.models import OneToOneField
     321        pk = self.model._meta.pk
     322        while isinstance(pk, OneToOneField):
     323            pk = pk.rel.to._meta.pk # Drill down until we find a "real" pk
     324        if pk.auto_created:
     325            self._pk_field_name = self.model._meta.pk.name
    324326            form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput)
    325327        super(BaseModelFormSet, self).add_fields(form, index)
    326328
Back to Top