Rzeczywiście, relacje O2O mogą być trudne, jeśli chcesz używać poleceń, takich jak dumpdata
i loaddata
, na przykład do tworzenia kopii zapasowych i przywracania wybranych obiektów w bazie danych.
Mamy podobny problem z naszym oprogramowaniem i odkryłem, że możliwym rozwiązaniem jest przesłonięcie metody save()
pod numerem django.core.serializers.base.DeserializedObject
, aby uzyskać uchwyt do momentu tuż przed zapisaniem "podwójnego" obiektu. W tym momencie możesz zdecydować się wyrzucić domyślną relację O2O stworzoną przez Django i pozwolić frameworkowi zapisać nowy lub zaktualizować go zapisanymi wartościami w pliku XML lub JSON.
Musiałbyś umieścić nadpisaną metodę gdzieś Django odbiera przed wykonaniem polecenia loaddata
. Jedną z możliwości jest utworzenie własnego polecenia, które z kolei wywołuje loaddata
. W module poleceń zainstalujesz zastąpienie. Podane są następujące szczegóły dotyczące tego rozwiązania:
- Testowane z Django 1.8.x
- Nasze O2O pole jest dołączony do Django
User
modelu
- Dla uproszczenia w tym przykładzie, zadzwonię pole dołączony 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
Możesz zmodyfikować kod powyżej, zamiast usuwania istniejącego obiektu, aktualizując go, jeśli, w klauzuli if hasattr(...)
, uniknąć usunięcia zaktualizować istniejący obiekt z wartości pochodzących z zserializowany obiekt i pomiń połączenie z numerem _original_save()
. Sprawi to, że kod będzie nieco bardziej związany z modelem, ponieważ może być konieczne zdefiniowanie pól do aktualizacji na istniejącym obiekcie. Rozwiązanie przedstawione powyżej nie zakłada założenia co do zawartości modelu.
znalazłeś rozwiązanie dla tego? –
Zalecam aktualizację django, jeśli masz taką możliwość. – Alp
Nie myśl, że będzie wiele obiektów w zrzutach danych lub utworzonych wiele razy. Czy możesz nam pokazać, jakie dane dump Ci daje? A także błąd danych loaddata? – Rohan