use*_*587 45 django django-models django-migrations
我正在使用该RunPython
方法创建数据迁移.但是,当我尝试在对象上运行方法时,没有定义.是否可以使用RunPython
?调用模型上定义的方法?
chh*_*yal 40
迁移中不提供模型方法,包括数据迁移.
但是有一些解决方法,它应该与调用模型方法非常相似.您可以在迁移中定义模拟要使用的模型方法的函数.
如果你有这个方法:
class Order(models.Model):
'''
order model def goes here
'''
def get_foo_as_bar(self):
new_attr = 'bar: %s' % self.foo
return new_attr
Run Code Online (Sandbox Code Playgroud)
您可以在迁移脚本中编写函数,如:
def get_foo_as_bar(obj):
new_attr = 'bar: %s' % obj.foo
return new_attr
def save_foo_as_bar(apps, schema_editor):
old_model = apps.get_model("order", "Order")
for obj in old_model.objects.all():
obj.new_bar_field = get_foo_as_bar(obj)
obj.save()
Run Code Online (Sandbox Code Playgroud)
然后在迁移中使用它:
class Migration(migrations.Migration):
dependencies = [
('order', '0001_initial'),
]
operations = [
migrations.RunPython(save_foo_as_bar)
]
Run Code Online (Sandbox Code Playgroud)
这样迁移就可以了.将会有一些重复的代码,但这并不重要,因为数据迁移应该是在应用程序的特定状态下的一次操作.
小智 14
你是否像文档中所说的那样打电话给你的模型?
def combine_names(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
Person = apps.get_model("yourappname", "Person")
for person in Person.objects.all():
person.name = "%s %s" % (person.first_name, person.last_name)
person.save()
Run Code Online (Sandbox Code Playgroud)
数据迁移 因为此时您无法直接导入模型:
from yourappname.models import Person
Run Code Online (Sandbox Code Playgroud)
更新
内部Django代码在此文件中django/db/migrations/state.py django.db.migrations.state.ModelState#construct_fields
def construct_fields(self):
"Deep-clone the fields using deconstruction"
for name, field in self.fields:
_, path, args, kwargs = field.deconstruct()
field_class = import_string(path)
yield name, field_class(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
在"假"模型实例中只有克隆字段:
MyModel.__module__ = '__fake__'
Run Code Online (Sandbox Code Playgroud)
这并没有回答OP,但可能仍然对某人有用。
不仅自定义模型方法在迁移中不可用,其他模型属性也是如此,例如用于模型字段的类“常量” choices
。请参阅文档中的示例。
在这种特定的边缘情况下,我们无法在迁移期间直接访问选择的历史值,但我们可以使用model _meta api从模型字段获取历史值,因为这些值包含在迁移中。
给出 Django 的Student
例子:
class Student(models.Model):
FRESHMAN = 'FR'
...
YEAR_IN_SCHOOL_CHOICES = [(FRESHMAN, 'Freshman'), ...]
year_in_school = models.CharField(
max_length=2,
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)
Run Code Online (Sandbox Code Playgroud)
Student.FRESHMAN
我们可以通过如下方式获取内部迁移的历史值:
...
Student = apps.get_model('my_app', 'Student')
YEAR_IN_SCHOOL_CHOICES = Student._meta.get_field('year_in_school').choices
...
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12564 次 |
最近记录: |