Search code examples
djangodatabasemigrationdatabase-migration

Django: set foreignkey to model of which `abstract` True...?


I've designed some model structures in django:

class Symbol(BaseModel):
    field1 = models.CharField(max_length=50)

    class Meta:
        abstract = True    

class DetailSymbol1(Symbol):
    field2 = models.CharField(max_length=50)

class DailyData(BaseModel):
    symbol = models.ForeignKey(DetailSymbol1)
    field3 = models.CharField(max_length=50)

After makemigrations and migrate done, I created some model objects:

In [1]: a = DetailSymbol1.objects.create(field1="a", field2="b")

In [2]: a.dailydata_set.create(field3="c")
Out[2]: <DailyData: DailyData object>

In [3]: a.dailydata_set.create(field3="d")
Out[3]: <DailyData: DailyData object>

In [4]: DailyData.objects.count()
Out[4]: 2

Now, What I want to do is to make Symbol model NOT abstract model and make DailyData have ForeignKey to Symbol, not DetailSymbol1. Here is the final code:

class Symbol(BaseModel):
    field1 = models.CharField(max_length=50)

class DetailSymbol1(Symbol):
    field2 = models.CharField(max_length=50)


class DailyData(BaseModel):
    symbol = models.ForeignKey(Symbol)
    field3 = models.CharField(max_length=50)

When I tried to migration, this prompt occured:

You are trying to add a non-nullable field 'symbol_ptr' to detailsymbol1 without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py
Select an option:

I have no idea what should I do with this message.

How can I deal with it without losing my data?

Need your help. Thanks


Solution

  • You can add a new foreign key to Symbol while keeping the old one.

    class DailyData(BaseModel):
        symbol = models.ForeignKey(DetailSymbol1)
        new_symbol = models.ForeignKey(Symbol)
    

    Then create a data migration to populate new_symbol.

    Finally you can remove the old foreign key to DetailSymbol1, and rename new_symbol to symbol.