Je l'ai fait essayer à marcher à travers la solution décrite par T la Pierre et le bien que je pense que c'est une superbe starter et explique la façon de faire les choses que j'ai rencontré quelques problèmes.
Je pense surtout que vous n'avez pas besoin de créer de l'entrée de la table de la classe parent plus, c'est à dire que vous n'avez pas besoin
new_movie.videofile_ptr = orm['media.VideoFile'].objects.create()
plus. Django va maintenant faire cela automatiquement pour vous (si vous avez les champs non null alors le ci-dessus ne fonctionne pas pour moi et m'a donné une erreur de base de données).
Je pense que c'est probablement en raison de changements dans django et du sud, voici une version qui a fonctionné pour moi sur ubuntu 10.10 avec django, 1.2.3 et sud 0.7.1. Les modèles sont un peu différentes, mais vous obtenez l'essentiel:
Configuration initiale
post1/models.py:
class Author(models.Model):
first = models.CharField(max_length=30)
last = models.CharField(max_length=30)
class Tag(models.Model):
name = models.CharField(max_length=30, primary_key=True)
class Post(models.Model):
created_on = models.DateTimeField()
author = models.ForeignKey(Author)
tags = models.ManyToManyField(Tag)
title = models.CharField(max_length=128, blank=True)
content = models.TextField(blank=True)
post2/models.py:
class Author(models.Model):
first = models.CharField(max_length=30)
middle = models.CharField(max_length=30)
last = models.CharField(max_length=30)
class Tag(models.Model):
name = models.CharField(max_length=30)
class Category(models.Model):
name = models.CharField(max_length=30)
class Post(models.Model):
created_on = models.DateTimeField()
author = models.ForeignKey(Author)
tags = models.ManyToManyField(Tag)
title = models.CharField(max_length=128, blank=True)
content = models.TextField(blank=True)
extra_content = models.TextField(blank=True)
category = models.ForeignKey(Category)
Il ya évidemment beaucoup de chevauchement, donc je voulais facteur de points communs
dans un poste de général du modèle et de ne garder que les différences dans l'autre
modèle de classes.
nouvelle configuration:
genpost/models.py:
class Author(models.Model):
first = models.CharField(max_length=30)
middle = models.CharField(max_length=30, blank=True)
last = models.CharField(max_length=30)
class Tag(models.Model):
name = models.CharField(max_length=30, primary_key=True)
class Post(models.Model):
created_on = models.DateTimeField()
author = models.ForeignKey(Author)
tags = models.ManyToManyField(Tag)
title = models.CharField(max_length=128, blank=True)
content = models.TextField(blank=True)
post1/models.py:
import genpost.models as gp
class SimplePost(gp.Post):
class Meta:
proxy = True
post2/models.py:
import genpost.models as gp
class Category(models.Model):
name = models.CharField(max_length=30)
class ExtPost(gp.Post):
extra_content = models.TextField(blank=True)
category = models.ForeignKey(Category)
Si vous souhaitez suivre, vous devrez d'abord obtenir ces modèles dans le sud:
$./manage.py schemamigration post1 --initial
$./manage.py schemamigration post2 --initial
$./manage.py migrate
La migration des données
Comment aller à ce sujet? La première écriture de la nouvelle application genpost et faire les premiers
les migrations avec les pays du sud:
$./manage.py schemamigration genpost --initial
(Je suis aide d' $
pour représenter les coquilles invite, donc ne tapez pas que.)
Créez ensuite le nouvelles classes SimplePost et ExtPost dans post1/models.py
et post2/models.py respectivement (ne pas supprimer le reste de la classe encore).
Puis créer schemamigrations pour ces deux ainsi:
$./manage.py schemamigration post1 --auto
$./manage.py schemamigration post2 --auto
Maintenant, nous pouvons appliquer l'ensemble de ces migrations:
$./manage.py migrate
Entrons dans le vif du sujet, la migration des données à partir de post1 et post2 à genpost:
$./manage.py datamigration genpost post1_and_post2_to_genpost --freeze post1 --freeze post2
Puis modifier genpost/migrations/0002_post1_and_post2_to_genpost.py:
class Migration(DataMigration):
def forwards(self, orm):
#
# Migrate common data into the new genpost models
#
for auth1 in orm['post1.author'].objects.all():
new_auth = orm.Author()
new_auth.first = auth1.first
new_auth.last = auth1.last
new_auth.save()
for auth2 in orm['post2.author'].objects.all():
new_auth = orm.Author()
new_auth.first = auth2.first
new_auth.middle = auth2.middle
new_auth.last = auth2.last
new_auth.save()
for tag in orm['post1.tag'].objects.all():
new_tag = orm.Tag()
new_tag.name = tag.name
new_tag.save()
for tag in orm['post2.tag'].objects.all():
new_tag = orm.Tag()
new_tag.name = tag.name
new_tag.save()
for post1 in orm['post1.post'].objects.all():
new_genpost = orm.Post()
# Content
new_genpost.created_on = post1.created_on
new_genpost.title = post1.title
new_genpost.content = post1.content
# Foreign keys
new_genpost.author = orm['genpost.author'].objects.filter(\
first=post1.author.first,last=post1.author.last)[0]
new_genpost.save() # Needed for M2M updates
for tag in post1.tags.all():
new_genpost.tags.add(\
orm['genpost.tag'].objects.get(name=tag.name))
new_genpost.save()
post1.delete()
for post2 in orm['post2.post'].objects.all():
new_extpost = p2.ExtPost()
new_extpost.created_on = post2.created_on
new_extpost.title = post2.title
new_extpost.content = post2.content
# Foreign keys
new_extpost.author_id = orm['genpost.author'].objects.filter(\
first=post2.author.first,\
middle=post2.author.middle,\
last=post2.author.last)[0].id
new_extpost.extra_content = post2.extra_content
new_extpost.category_id = post2.category_id
# M2M fields
new_extpost.save()
for tag in post2.tags.all():
new_extpost.tags.add(tag.name) # name is primary key
new_extpost.save()
post2.delete()
# Get rid of author and tags in post1 and post2
orm['post1.author'].objects.all().delete()
orm['post1.tag'].objects.all().delete()
orm['post2.author'].objects.all().delete()
orm['post2.tag'].objects.all().delete()
def backwards(self, orm):
raise RuntimeError("No backwards.")
Maintenant appliquer ces migrations:
$./manage.py migrate
Ensuite, vous pouvez supprimer le maintenant les parties redondantes à partir de post1/models.py et post2/models.py et puis créer schemamigrations de mettre à jour les tables pour le nouvel état:
$./manage.py schemamigration post1 --auto
$./manage.py schemamigration post2 --auto
$./manage.py migrate
Et cela devrait suffire! Espérons que tout cela fonctionne et que vous avez refait votre modèles.