2014-09-01 44 views
3

我想一个新列添加到现有表中的另一价值,但我想给它依赖于已有数据的默认值:Django的迁移/南:新列取默认值从相同的记录

例如每个记录都有一个start_date。现在我想添加一个open_until列,并且我想用它填充每个现有记录的start_date的值。 (即将到来的记录将可以选择不同的值)

有没有一种友好的方式来做到这一点?

+0

不是数据库级别,请在forms.py中执行此操作。 – elmonkeylp 2014-09-01 16:33:02

+0

@elmonkeylp但这会如何定位所有以前的条目? – confused00 2014-09-01 16:49:41

+0

在数据库中设置了默认值后,就已经完成了。 – elmonkeylp 2014-09-01 16:54:02

回答

-1

正如我回答你,在数据库级别设置一个动态的默认值是没有必要的,如果你是一个框架:)

最好的办法,我认为,是设置你列的值工作保存记录前的视图。

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 

对于以前的条目,做一个视图调用只需一次,然后遍历所有记录并保存新列的值umn根据订单栏的值。

事情是这样的:

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!!") 
+2

这是一堆黑客。 Op要求迁移旧数据,而不是如何处理新创建的记录。数据迁移是正确的Djangoish做法。创建一次性视图?为什么?如果你真的想避免数据迁移,比如说,你还在原型设计中,只需从CLI运行该功能,不需要构建视图...... Hacky hacky hacky – 2016-07-01 09:40:33

11

你也可以做到这一点内南。唯一需要注意的是,你需要两个步骤:

  1. 一个架构迁移,增加了open_until列

    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

  2. 一个数据迁移,填补现有具有该列值的行

    $ 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() 
    

可选)在步骤1中,你可以提供一个临时的默认值,或使其可选的,并且增加一个第三步骤

  • A 模式迁移,它使open_until列成为强制性的。