【问题标题】:You are trying to add a non-nullable field (id)... when trying to makemigrations您正在尝试添加一个不可为空的字段 (id)... 尝试进行迁移时
【发布时间】:2018-06-10 01:29:53
【问题描述】:

发生了什么事:

  1. 我创建了以下模型:

    类锻炼(models.Model):

    datetime = models.DateTimeField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    lifts = fields.LiftsField()
    cardio = JSONField()
    
    def __str__(self):
        return str(self.datetime)+" "+self.user.email
    
    __repr__ = __str__
    

    类活动(models.Model):

    name = models.CharField(max_length = 100)
    
    def __str__(self):
        return self.name
    __repr__ = __str__
    

    类 CardioActivity(Activity): 通过

    类 LiftActivity(Activity): 通过

  2. 我跑了makemigrationsmigrate

    workoutcal/migrations/0002_activity_cardioactivity_liftactivity_workout.py - Create model Activity - Create model Workout - Create model CardioActivity - Create model LiftActivity

0002_activity_cardioactivity_liftactivity_workout.py

class Migration(migrations.Migration):

    dependencies = [
        ('workoutcal', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Activity',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100)),
            ],
        ),
        migrations.CreateModel(
            name='Workout',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('datetime', models.DateTimeField()),
                ('lifts', workoutcal.fields.LiftsField()),
                ('cardio', django.contrib.postgres.fields.jsonb.JSONField()),
                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
            ],
        ),
        migrations.CreateModel(
            name='CardioActivity',
            fields=[
                ('activity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='workoutcal.Activity')),
            ],
            bases=('workoutcal.activity',),
        ),
        migrations.CreateModel(
            name='LiftActivity',
            fields=[
                ('activity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='workoutcal.Activity')),
            ],
            bases=('workoutcal.activity',),
        ),
    ]
  1. 然后我把Activity 类变成了一个元类:

    类活动(models.Model):

    name = models.CharField(max_length = 100)
    
    def __str__(self):
        return self.name
    __repr__ = __str__
    
    class Meta:
        abstract = True
    
  2. 又尝试makemigrations

    (workout) Sahands-MBP:workout sahandzarrinkoub$ python manage.py makemigrations You are trying to add a non-nullable field 'id' to cardioactivity 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

此消息的原因是什么?这对我来说没有任何意义。 CardioActivity 自上次迁移以来甚至没有更改,它怎么会抱怨我试图添加 id 字段??

编辑:数据库中有什么?

当我检查数据库中的CardioActivity 表时,我发现:

workout=# \dt
                     List of relations
 Schema |               Name               | Type  | Owner 
--------+----------------------------------+-------+-------
 public | auth_group                       | table | admin
 public | auth_group_permissions           | table | admin
 public | auth_permission                  | table | admin
 public | django_admin_log                 | table | admin
 public | django_content_type              | table | admin
 public | django_migrations                | table | admin
 public | django_session                   | table | admin
 public | workoutcal_activity              | table | admin
 public | workoutcal_cardioactivity        | table | admin
 public | workoutcal_liftactivity          | table | admin
 public | workoutcal_user                  | table | admin
 public | workoutcal_user_groups           | table | admin
 public | workoutcal_user_user_permissions | table | admin
 public | workoutcal_workout               | table | admin
(14 rows)

workout=# SELECT * FROM workoutcal_cardioactivity;
 activity_ptr_id 
-----------------
(0 rows)

如您所见,表中甚至没有任何现有行!那么 Django 怎么能说它需要填充现有的行呢?

【问题讨论】:

    标签: django


    【解决方案1】:

    Django makemigration 不会检查表中是否有任何记录。因此,如果您将新字段添加到模型中,它必须具有默认值,或者您必须为该字段添加 null=True

    【讨论】:

      猜你喜欢
      • 2016-01-18
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 2021-08-25
      • 2016-05-09
      • 1970-01-01
      • 2022-01-28
      相关资源
      最近更新 更多