のために1.7で廃止さに見えますが実際には、dumpdata
とloaddata
などのコマンドを使用して、データベース内の選択オブジェクトをバックアップおよび復元する場合、O2Oの関係は扱いにくくなる可能性があります。
私たちのソフトウェアでも同様の問題があり、save()
メソッドをdjango.core.serializers.base.DeserializedObject
で上書きして、実際に「double」オブジェクトが保存される直前の時点までに処理することが可能であることがわかりました。この時点で、Djangoによって作成されたデフォルトのO2O関係を破棄し、フレームワークに新しいものを保存させるか、XMLまたはJSONファイルの保存された値で更新することができます。
loaddata
コマンドが実行される前に、Djangoが上書きする方法を上書きする必要があります。 1つの可能性は独自のコマンドを作成して、loaddata
を呼び出すことです。コマンドモジュールでは、オーバーライドをインストールします。このソリューションに関する以下の詳細が暗示されています。
- Django 1.8でテスト済みです。X
- 当社のO2Oフィールドがこの例では単純化のためにはDjango
User
モデル
- に装着され、私は付属のO2Oフィールド
Attached
と呼ぶことにします。
# Overrides deserialization to affect OneToOneFields for Users correctly
import django.core.serializers.base
from django.contrib.auth.models import User
from your.attached.models import Attached #model with O2O field to User
_original_save = django.core.serializers.base.DeserializedObject.save
def save(self, *args, **kwargs):
if isinstance(self.object, Attached):
# if the user in question has an attached object, delete it
user = User.objects.get(pk=self.object.user_id)
if hasattr(user, 'attached'): user.attached.delete()
# use the built-in function for all other cases
_original_save(self, *args, **kwargs)
django.core.serializers.base.DeserializedObject.save = save
あなたは、if hasattr(...)
句で、あなたの場合はそれを更新し、代わりに既存のオブジェクトを削除する、のために上記のコードを変更、削除を避けるため、からの値を持つ既存のオブジェクトを更新することができます。シリアル化されたオブジェクトを呼び出し、_original_save()
への呼び出しをスキップします。既存のオブジェクトでどのフィールドを更新するかを定義する必要があるかもしれないので、コードをモデル化するためにもう少し複雑になります。上に示した解は、モデルの内容を前提にしていません。
解決方法を見つけましたか? –
これを行う必要がある場合は、djangoを更新することをお勧めします。 – Alp
ダンプデータに複数のオブジェクトが存在すると思われたり、複数回作成されたりしません。ダンプデータがあなたに与えてくれることを教えてくれますか?また、loaddataのエラー? – Rohan