且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Django 1.7.1:子模型,删除对父模型的所有引用,并使子模型从祖父继承

更新时间:2023-02-05 10:34:14

不知道是否有一个更简单的方法来做这个但是....



尝试创建一个继承A的C'
然后创建一个创建C'每个C实例。
(删除C的所有实例)



如果要保留名称C,请更新C的架构,然后从C'实例重新填充C。



希望有帮助。 :)


I have three models like:

class A(models.Model):
    pass
    # more fields here

class B(A):
    pass
    # more fields here

class C(B):
    pass
    # more fields here

New requirements require me to instead have:

class A(models.Model):
    pass
    # more fields here

class B(A):
    pass
    # more fields here

class C(A):
    pass
    # more fields here

The code is already running in production, so I need to do some data migration. Thinking that it would work smoothly, here's what I planned to do:

  1. Save each C's b_ptr_id to a temporary field.
  2. Remove C's inheritance from B (deleting b_ptr_id in the process).
  3. Make C inherit from A (adding an a_ptr_id in the process).
  4. For each C, copy the value stored in the temporary field to a_ptr_id.
  5. Delete the temporary field.

My problem is with step 3. When I try to make inherit C from A, I'm getting the error django.core.exceptions.FieldError: Local field 'a_ptr' in class 'C' ***es with field of similar name from base class 'B'. So it seems like Django still "remembers" that C used to inherit from B, even if b_ptr_id is no longer a column of C in the database. How do I make it forget so that I can move on? Or is there a better way to make child models inherit from its grandparent model instead of its parent model?

Not sure if there's an easier way to do this but....

Try creating a C' that inherits A. Then create a program that creates a C' instance of each C instance. (Delete all instance of C afterwards)

If you want to keep the name C, update schema for C and then repopulate C from the C' instances.

Hope it helps. :)