Django


1038 浏览 5 years, 3 months

4.7 Django中Model fields位置的排序

版权声明: 转载请注明出处 http://www.codingsoho.com/

遵从DRY原则,在定义model的时候,我尽量使用继承的方法去定义一些类似的model,但是碰到一个问题,就是model里的fields位置好像不受控制,比如继承类的field总是排在基类的后面

下面例子:在继承类DormEvaluationItemCriteriaTest里面添加一个新的新的field: check_date,执行migration之后,这个变量总是排在最后

class AbstractMonthlySafetyCheckItemCriteriaCategory(models.Model):
    category = models.CharField(_("category"), max_length=30, blank=False, null=False) 
    class Meta:
        abstract = True

class DormEvaluationItemCriteriaTest(AbstractMonthlySafetyCheckItemCriteriaCategory):
    check_date = models.DateField(_('Check Date'),auto_now_add=True, auto_now=False) 
    class Meta:
        abstract = False   

class Migration(migrations.Migration): 
    dependencies = [
        ('monthlyinspection', '0024_auto_20180219_0028'),
    ] 
    operations = [
        migrations.CreateModel(
            name='DormEvaluationItemCriteriaTest',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('category', models.CharField(max_length=30, verbose_name='category')),
                ('check_date', models.DateField(auto_now_add=True, verbose_name='Check Date')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]

后来我试了一下把所有的field都定义在虚基类里面,但是field的排序并不跟基类的位置有关,而且由基类在model文件的定义顺序决定的,

比如定义了一下三个虚基类

class AbstractMonthlySafetyCheckItemCriteriaCategory(models.Model):
    category = models.CharField(_("category"), max_length=30, blank=False, null=False) 
    class Meta:
        abstract = True

class AbstractMonthlySafetyCheckItemCriteria(models.Model):
    index = models.CharField(_("index"), max_length=30, blank=False, null=False, unique=True)
    check_item = models.CharField(_('check item'), max_length=130, blank=False, null=False)
    check_criteria = models.TextField(_('check criteria'), max_length=500, blank=False, null=False) 
    class Meta:
        abstract = True

class AbstractMonthlySafetyCheckItemCriteriaScore(models.Model):
    score_criteria = models.TextField(_('score criteria'), max_length=500, blank=True, null=True)
    score_reference = models.CharField(_('score reference'), max_length=30, blank=True, null=True)
    comments = models.TextField(_('comments'), max_length=500, blank=True, null=True) 
    class Meta:
        abstract = True

那么,当我定义如下的继承类时,不管三个基类的排放顺序如何,migrations之后生成的field的位置都是固定的

class DormEvaluationItemCriteriaTest(                
                AbstractMonthlySafetyCheckItemCriteriaCategory,
                AbstractMonthlySafetyCheckItemCriteria,
                AbstractMonthlySafetyCheckItemCriteriaScore
                ): 
    class Meta:
        abstract = False  

或者

class DormEvaluationItemCriteriaTest(                
                AbstractMonthlySafetyCheckItemCriteria,
                AbstractMonthlySafetyCheckItemCriteriaScore,
                AbstractMonthlySafetyCheckItemCriteriaCategory
                ):

Field的顺序跟class在文件里的定义顺序是一致的

class Migration(migrations.Migration): 
    dependencies = [
        ('monthlyinspection', '0024_auto_20180219_0028'),
    ] 
    operations = [
        migrations.CreateModel(
            name='DormEvaluationItemCriteriaTest',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('category', models.CharField(max_length=30, verbose_name='category')),
                ('index', models.CharField(max_length=30, unique=True, verbose_name='index')),
                ('check_item', models.CharField(max_length=130, verbose_name='check item')),
                ('check_criteria', models.TextField(max_length=500, verbose_name='check criteria')),
                ('score_criteria', models.TextField(blank=True, max_length=500, null=True, verbose_name='score criteria')),
                ('score_reference', models.CharField(blank=True, max_length=30, null=True, verbose_name='score reference')),
                ('comments', models.TextField(blank=True, max_length=500, null=True, verbose_name='comments')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]

有什么办法可以手动的调整field的顺序吗?

Django model 不允许域覆盖

https://docs.djangoproject.com/en/2.0/topics/db/models/#field-name-hiding-is-not-permitted

参考 https://stackoverflow.com/questions/19025586/django-model-inheritance-overriding-fields

In normal Python class inheritance, it is permissible for a child class to override any attribute from the parent class. In Django, this is not permitted for attributes that are Field instances (at least, not at the moment). If a base class has a field called author, you cannot create another model field called author in any class that inherits from that base class.