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?

+3


source to share


2 answers


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

      

-1


source


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

  1. schema migration , which makes the open_until column required.
+11


source







All Articles