您尝试在尝试进行迁移时尝试添加不可为空的字段(ID)

时间:2017-12-29 16:24:30

标签: django

这里发生了什么:

  1. 我创建了以下模型:

    class Workout(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__
    

    class Activity(models.Model):

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

    班级CardioActivity(活动):     通

    类LiftActivity(Activity):     通

  2. 我跑了makemigrationsmigrate

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

  3. 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类转换为元类:

      class 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

    3. 此消息的原因是什么?这对我没有任何意义。自上次迁移以来,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怎么能说它需要填充现有的行?

1 个答案:

答案 0 :(得分:0)

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