Question

Je suis un sous-classement modèle existant. Je veux un grand nombre des membres de la classe mère maintenant, au contraire, être membres de la classe enfant.

Par exemple, j'ai un Swallow modèle. Maintenant, je fais EuropeanSwallow (Swallow) et AfricanSwallow (Swallow). Je veux prendre un peu mais pas tous les objets Avalez-les faire soit EuropeanSwallow ou AfricanSwallow, selon qu'ils sont migratrices.

Comment puis-je les déplacer?

Était-ce utile?

La solution

Je sais que c'est beaucoup plus tard, mais je devais faire quelque chose de similaire et ne pouvait pas trouver beaucoup. J'ai trouvé la réponse enfouie dans un code source , mais aussi écrit un exemple-méthode de classe qui suffirait.

class AfricanSwallow(Swallow):

    @classmethod
    def save_child_from_parent(cls, swallow, new_attrs):
        """
        Inputs:
        - swallow: instance of Swallow we want to create into AfricanSwallow
        - new_attrs: dictionary of new attributes for AfricanSwallow

        Adapted from: 
        https://github.com/lsaffre/lino/blob/master/lino/utils/mti.py
        """
        parent_link_field = AfricanSwallow._meta.parents.get(swallow.__class__, None)
        new_attrs[parent_link_field.name] = swallow
        for field in swallow._meta.fields:
            new_attrs[field.name] = getattr(swallow, field.name)
        s = AfricanSwallow(**new_attrs)
        s.save()
        return s

Je ne pouvais pas comprendre comment obtenir ma validation de formulaire pour travailler avec cette méthode cependant; il pourrait certainement être amélioré plus; signifie probablement une refactorisation de base de données pourrait être la meilleure solution à long terme ...

Autres conseils

Il est un peu un hack, mais cela fonctionne:

swallow = Swallow.objects.get(id=1)
swallow.__class__ = AfricanSwallow
# set any required AfricanSwallow fields here
swallow.save()

Cela dépend de quel genre d'héritage de modèle que vous utiliserez. Voir http://docs.djangoproject.com/en/dev / sujets / db / modèles / # modèle d'héritage pour les trois types classiques. Comme il semble que vous voulez des objets Swallow qui exclut la classe de base abstraite.

Si vous voulez stocker différentes informations dans le db pour Swallow vs vs AfricanSwallow EuropeanSwallow, alors vous aurez envie d'utiliser MTI. Le plus gros problème avec MTI que le modèle django officiel recommande que le polymorphisme ne fonctionne pas correctement. Autrement dit, si vous allez chercher un objet Swallow de la DB qui est en fait un objet AfricanSwallow, vous ne recevrez pas une instance o AfricanSwallow. (Voir cette question .) Quelque chose comme django-modèle-utils InheritanceManager peut aider à surmonter cela.

Si vous avez des données réelles que vous devez préserver grâce à ce changement, utilisez migrations Sud . Faire deux migrations -. Première qui change le schéma et une autre qui copie les données d'objets appropriés dans les sous-classes

Je suggère d'utiliser django-modèle-utils de InheritanceCastModel. Ceci est une mise en œuvre qui me plaît. Vous pouvez trouver beaucoup plus djangosnippets et certains blogs, mais après avoir tout ce que je leur cuvette choisi celui-ci. Espérons que cela aide.

Une autre (pas à jour) approche: Si vous ne vous dérange pas l'id parent maintenant vous pouvez simplement créer de nouvelles instances de marque enfant des attrs des parents. Voilà ce que je l'ai fait:

ids = [s.pk for s in Swallow.objects.all()]
# I get ids list to avoid memory leak with long lists
for i in ids:
    p = Swallow.objects.get(pk=i)
    c = AfricanSwallow(att1=p.att1, att2=p.att2.....)
    p.delete()
    c.save()

Une fois que cela fonctionne, une nouvelle instance AfricanSwallow sera créé en remplaçant chaque instance initiale Swallow Peut-être que cela vous aidera quelqu'un:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top