| 1 | from django.db.models import AutoField
|
|---|
| 2 | from django.db.models import ForeignKey
|
|---|
| 3 |
|
|---|
| 4 | def save_with_refresh(obj):
|
|---|
| 5 | """
|
|---|
| 6 | https://code.djangoproject.com/ticket/10811
|
|---|
| 7 |
|
|---|
| 8 | Refreshes all foreign keys. Should be used before saving to avoid the
|
|---|
| 9 | problem below
|
|---|
| 10 |
|
|---|
| 11 | child = Child.create()
|
|---|
| 12 | parent = Parent.create()
|
|---|
| 13 | parent.child = child
|
|---|
| 14 | child.save() pk set to 123
|
|---|
| 15 | parent.child.id result properly set to 123
|
|---|
| 16 | parent.save() django incorrectly stores NULL for parent.child
|
|---|
| 17 |
|
|---|
| 18 | """
|
|---|
| 19 |
|
|---|
| 20 | # attname.......Presents the property of this model in which field the
|
|---|
| 21 | # duplicated primary key is saved in the database.
|
|---|
| 22 | # name..........Presents the reference to the object where the original
|
|---|
| 23 | # primary key is saved.
|
|---|
| 24 | fks = [(f.attname, f.name) for f in obj._meta.local_fields if type(f) == ForeignKey]
|
|---|
| 25 |
|
|---|
| 26 | for (attname, fk_ref) in fks:
|
|---|
| 27 | # Update attribute if it is defined but not yet stored as an id
|
|---|
| 28 | if not getattr(obj, attname) and getattr(obj, fk_ref):
|
|---|
| 29 |
|
|---|
| 30 | # raise an error if a primary key of the related object does
|
|---|
| 31 | # not exist (if it is not saved until now)
|
|---|
| 32 | if getattr(obj, fk_ref).pk == None:
|
|---|
| 33 | raise ValueError("Cannot find a primary key for " + str(fk_ref) +
|
|---|
| 34 | " as a foreign key in an instance of " + obj.__class__.__name__ +
|
|---|
| 35 | ". Have you already saved the " + str(fk_ref) + " object?")
|
|---|
| 36 |
|
|---|
| 37 | else:
|
|---|
| 38 | # force django to reset id
|
|---|
| 39 | setattr(obj, fk_ref, getattr(obj, fk_ref))
|
|---|
| 40 |
|
|---|
| 41 | obj.save()
|
|---|