我想给一个已经存在的表添加一列,并为其赋予依赖于现有数据的默认值:
例如,每条记录都有一个“开始日期”。现在我想添加一个“截止日期”列,并将其填充为每个现有记录的“开始日期”值。(即即将到来的记录将能够选择不同的值)
是否有一种友好的方法来实现这个?
例如,每条记录都有一个“开始日期”。现在我想添加一个“截止日期”列,并将其填充为每个现有记录的“开始日期”值。(即即将到来的记录将能够选择不同的值)
是否有一种友好的方法来实现这个?
您也可以在South内部完成此操作。唯一的注意事项是需要两个步骤:
A schema migration that adds the open_until column
from django.db import models
import datetime
class MyModel(models.Model):
start_date = models.DateField(),
open_until = models.DateField(default=datetime.date.today),
$ python manage.py schemamigration --auto appname
A data migration that fills existing rows with the value of that other column
$ python manage.py datamigration appname populate_open_until
import datetime
class Migration(DataMigration):
def forwards(self, orm):
"Set open_until value to that of start_date for existing rows"
for t in orm.MyModel.objects.all():
t.open_until = t.start_date
t.save()
def backwards(self, orm):
"Revert back to default"
for t in orm.MyModel.objects.all():
t.open_until = datetime.date.today
t.save()
(可选) 在第一步中,您可以提供一个临时默认值或将其设置为可选并添加第三步。
在Python 3.8中,我首先向MyApp
模型文件添加字段,代码如下:
from django.db import models
import datetime
class MyModel(models.Model):
start_date = models.DateField(),
open_until = models.DateField(default=datetime.date.today),
manage.py makemigrations
之后,将这些行添加到新的迁移文件中:def forward(apps, schema_editor):
my_model_objects = apps.get_model('MyApp', 'MyModel').objects.all()
for t in my_model_objects:
t.open_until = t.start_date
t.save()
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
operations = [
" the base operations is here " ,
migrations.RunPython(forward, reverse),
]
正如我之前回复你的那样,如果你正在使用框架,那么在数据库级别设置动态默认值是不必要的 :)
我认为最好的方法是在保存记录之前,在视图中设置列的值。
models.py
from django.db import models
class MyModel(models.Model):
start_date = models.DateField(),
open_until = models.DateField(),
forms.py 从django.forms导入ModelForm
class MyForm(forms.ModelForm):
model = MyModel
fields = ('start_date')
类视图
from django.http import HttpResponse
from django.views.generic import CreateView
from .models import MyModel
MyView(CreateView):
form_class = MyForm
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
submitted_form = form.save(commit=False)
submitted_form.open_until = form.cleaned_data["start_date"]
submitted_form.save()
# return an HttpResponse here
对于之前的条目,创建一个视图只调用一次,然后循环遍历所有记录并根据顺序列的值保存新列的值。
类似这样:
from django.http import HttpResponse
def set_open_until_values(request)
records = MyModel.objects.all()
for record in records:
record.open_until = record.start_date
record.save()
return HttpResponse("Done!!")