不推荐django字段,并在不破坏现有代码的情况下进行迁移。
django-deprecation的Python项目详细描述
Django折旧
不推荐Django字段,并在不破坏现有代码的情况下进行迁移。
安装
pip install django-deprecation
用法
tl;dr
# Before:classAlbum(models.Model):name=models.CharField(max_length=50)# After:classAlbum(models.Model):name=DeprecatedField('title')title=models.CharField(max_length=50)assertalbum.name==album.titleassertlist(Album.objects.filter(name='foo'))==list(Album.objects.filter(title='foo'))
详细说明
假设我们有以下型号:
fromdjango.dbimportmodelsclassMusician(models.Model):name=models.CharField(max_length=50)classAlbum(models.Model):musician=models.ForeignKey(Musician,on_delete=models.CASCADE)name=models.CharField(max_length=100)
现在,出于某种原因,假设我们想将字段Album#musician
重命名为Album#artist
。
所以我们使用 RenameField 操作。问题是,使用旧字段的任何现有代码都会被破解。
我们可以创建一个属性作为别名:
classAlbum(models.Model):artist=models.ForeignKey(Musician,on_delete=models.CASCADE)name=models.CharField(max_length=100)@propertydefmusician(self):returnself.artist@musician.setterdefmusician(self,value):self.artist=value
但是任何使用
QuerySet#filter
如果使用musician
字段,则会中断。
这就是django-deprecation
有用的地方。
我们将musician
字段设置为DeprecatedField
,并将其指向artist
字段:
fromdjango_deprecationimportDeprecatedFieldclassAlbum(models.Model):artist=models.ForeignKey(Musician,on_delete=models.CASCADE)musician=DeprecatedField('artist')name=models.CharField(max_length=100)
现在,下面的代码片段将起作用:
from.modelsimportAlbum,Musicianalbum=Album.objects.first()assertalbum.musician==album.artistnew_musician=Musician.objects.create(first_name='John',last_name='Doe',instrument='Guitar',)album.musician=new_musicianassertalbum.artist==new_musiciannew_musician_album=Album.objects.filter(musician=new_musician,).first()new_artist_album=Album.objects.filter(artist=new_musician,).first()assertnew_musician_album==new_artist_album
如果要控制如何报告错误,
用自定义函数替换DeprecatedField.warn
函数:
fromdjango_deprecationimportDeprecatedFielddefwarn_function(message):# do stuffimportwarningswarnings.warn(message,DeprecationWarning)DeprecatedField.warn=warn_function