栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用South重构具有继承性的Django模型

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用South重构具有继承性的Django模型

请查看Paul的以下回应,以获取有关与Django / South较新版本兼容的一些说明。


这似乎是一个有趣的问题,并且我正成为南方的忠实拥护者,所以我决定对此进行一些研究。我根据您上面描述的摘要构建了一个测试项目,并成功地使用South执行了您要的迁移。在使用代码之前,有一些注意事项:

  • 南方文档建议将架构迁移和数据迁移分开进行。我在这方面也遵循了。

  • 在后端,Django通过在继承模型上自动创建OneToOne字段来表示继承的表

  • 理解了这一点,我们的South迁移需要手动正确地处理OneToOne字段,但是,在尝试进行此操作时,South(或Django本身)似乎无法在多个具有相同名称的继承表上创建一个OneToOne。因此,我将Movies / tv应用程序中的每个子表重命名为其各自的应用程序(即MovieVideoFile / ShowVideoFile)。

  • 在使用实际的数据迁移代码时,South似乎更喜欢先创建OneToOne字段,然后再为其分配数据。在创建期间将数据分配给OneToOne字段会导致South窒息。(为南方的所有凉爽做出公平的妥协)。

说了这么多,我试图保留发出的控制台命令的日志。我将在必要时插入评论。最终代码在底部。

命令历史

django-admin.py startproject southtestmanage.py startapp moviesmanage.py startapp tvmanage.py syncdbmanage.py startmigration movies --initialmanage.py startmigration tv --initialmanage.py migratemanage.py shell          # added some fake data...manage.py startapp mediamanage.py startmigration media --initialmanage.py migrate# edited pre, wrote new models, but left old ones intactmanage.py startmigration movies unified-videofile --auto# create a new (blank) migration to hand-write data migrationmanage.py startmigration movies videofile-to-movievideofile-data manage.py migrate# edited pre, wrote new models, but left old ones intactmanage.py startmigration tv unified-videofile --auto# create a new (blank) migration to hand-write data migrationmanage.py startmigration tv videofile-to-movievideofile-datamanage.py migrate# removed old VideoFile model from appsmanage.py startmigration movies removed-videofile --automanage.py startmigration tv removed-videofile --automanage.py migrate

为了节省空间,并且由于模型最终总是看起来相同,因此我仅使用“电影”应用程序进行演示。

电影/models.py

from django.db import modelsfrom media.models import VideoFile as baseVideoFile# This model remains until the last migration, which deletes # it from the schema.  Note the name conflict with media.modelsclass VideoFile(models.Model):    movie = models.ForeignKey(Movie, blank=True, null=True)    name = models.CharField(max_length=1024, blank=True)    size = models.IntegerField(blank=True, null=True)    ctime = models.DateTimeField(blank=True, null=True)class MovieVideoFile(baseVideoFile):    movie = models.ForeignKey(Movie, blank=True, null=True, related_name='shows')

电影/迁移/0002_unified-videofile.py(模式迁移)

from south.db import dbfrom django.db import modelsfrom movies.models import *class Migration:    def forwards(self, orm):        # Adding model 'MovieVideoFile'        db.create_table('movies_movievideofile', ( ('videofile_ptr', orm['movies.movievideofile:videofile_ptr']), ('movie', orm['movies.movievideofile:movie']),        ))        db.send_create_signal('movies', ['MovieVideoFile'])    def backwards(self, orm):        # Deleting model 'MovieVideoFile'        db.delete_table('movies_movievideofile')

电影/迁移/0003_videofile-to-movievideofile-data.py(数据迁移)

from south.db import dbfrom django.db import modelsfrom movies.models import *class Migration:    def forwards(self, orm):        for movie in orm['movies.videofile'].objects.all(): new_movie = orm.MovieVideoFile.objects.create(movie = movie.movie,) new_movie.videofile_ptr = orm['media.VideoFile'].objects.create() # videofile_ptr must be created first before values can be assigned new_movie.videofile_ptr.name = movie.name new_movie.videofile_ptr.size = movie.size new_movie.videofile_ptr.ctime = movie.ctime new_movie.videofile_ptr.save()    def backwards(self, orm):        print 'No Backwards'

南真棒!

好的,标准免责声明:您正在处理实时数据。我在这里已经为您提供了工作代码,但是请使用

--db-dry-run
来测试您的架构。在尝试任何操作之前,请务必进行备份,并且通常要格外小心。

兼容性通知

我将保留原始消息,但South已将命令更改

manage.py startmigration
manage.py schemamigration



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/419897.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号