Ticket #8892: 8892.patch

File 8892.patch, 2.7 KB (added by blacklwhite, 9 years ago)
  • django/db/models/base.py

     
    449449            return getattr(self, field_name)
    450450        return getattr(self, field.attname)
    451451
     452       def refresh_foreign_keys(self):
     453        """
     454        Refreshes all foreign keys. Should be used before saving. If the primary
     455        key of a foreign key changed after setting the related object to the
     456        model it can not be refreshed automatically.
     457        """
     458
     459        # Get all foreign keys of this model. Attname and name must be equal.
     460        # attname.......Presents the property of this model in which field the
     461        #               duplicated primary key is saved in the database.
     462        # name..........Presents the reference to the object where the original
     463        #               primary key is saved.
     464        fks = [(f.attname, f.name) for f in self._meta.local_fields if type(f) == ForeignKey]
     465
     466        for (db_ref, fk_ref) in fks:
     467            # If db_ref already exists we do not make unneccessary db-queries,
     468            # because the related object is already set in the correct.
     469            if not getattr(self, db_ref) and hasattr(self, fk_ref):
     470
     471                # raise an error if a primary key of the related object does
     472                # not exist (if it is not saved until now)
     473                if getattr(self, fk_ref).pk == None:
     474                    print type(str(fk_ref))
     475                    raise ValueError("Cannot find a primary key for " + str(fk_ref) +
     476                        " as a foreign key in an instance of " + self.__class__.__name__ +
     477                        ". Have you already saved the " + str(fk_ref) + " object?")
     478
     479                # If the duplicated key is not the real one, set the real one
     480                if getattr(self, db_ref) != getattr(self, fk_ref).pk:
     481                    setattr(self, db_ref, getattr(self, fk_ref).pk)
     482               
    452483    def save(self, force_insert=False, force_update=False, using=None):
    453484        """
    454485        Saves the current instance. Override this in a subclass if you want to
     
    486517        if origin and not meta.auto_created:
    487518            signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using)
    488519
     520        # Refresh the references of foreign keys. Primary keys of referenced
     521        # objects may changed in the object but not in the database field of
     522        # this model.
     523        self.refresh_foreign_keys()
     524                                               
    489525        # If we are in a raw save, save the object exactly as presented.
    490526        # That means that we don't try to be smart about saving attributes
    491527        # that might have come from the parent class - we just save the
Back to Top