Django / South migrations: new column defaults to a different value from the same record
I want to add a new column to an already existing table, but I want to give it a default value depending on the already existing data:
eg. Each entry has a start_date
. Now I want to add a column open_until
and I want to populate it with a value start_date
for each existing record. (upcoming entries will be able to choose a different value)
Is there a friendly way to do this?
source to share
As I answered you, setting a dynamic default at the database level is not required if you are working with a framework :)
The best way I think is to set the value of your column in the view before saving the record.
models.py
from django.db import models
class MyModel(models.Model):
start_date = models.DateField(),
open_until = models.DateField(),
forms.py from django.forms import ModelForm
class MyForm(forms.ModelForm):
model = MyModel
fields = ('start_date')
class type
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
For the previous records, create a view to call only once, then skip all records and store the new column values according to the order column value.
Something like that:
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!!")
source to share
You can also do this in the south. The only caveat is that you need two steps to do this:
-
A schema migration that adds an 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 transfer 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()
(not necessary). In step 1 you can provide a temporary default value or make it optional and add a third step
- schema migration , which makes the open_until column required.
source to share