您试图在没有默认值的情况下向userprofile添加不可为空的字段"new_field"

Irm*_*nis 85 python django

我知道从Django 1.7我不需要使用South或任何其他迁移系统,所以我只是使用简单的命令 python manage.py makemigrations

但是,我得到的只是这个错误:

You are trying to add a non-nullable field 'new_field' to userprofile without a default;
we can't do that (the database needs something to populate existing rows).
Run Code Online (Sandbox Code Playgroud)

这是models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    website = models.URLField(blank=True)
    new_field = models.CharField(max_length=140)
Run Code Online (Sandbox Code Playgroud)

有什么选择?

Tom*_*asz 71

如果您处于早期开发周期并且不关心当前的数据库数据,则可以将其删除然后进行迁移.但首先你需要清理迁移目录并从表中删除它的行(django_migrations)

rm  your_app/migrations/*

rm db.sqlite3
python manage.py makemigrations
python manage.py migrate
Run Code Online (Sandbox Code Playgroud)

  • 还有一件事.你需要清理迁移表,例如:`mysql -u [user] [database] -e"从django_migrations中删除app = [your_app]"` (7认同)
  • 还要确保不要从迁移中删除`__init__.py`,或者在之后恢复它,否则 makemigrations 将不起作用 /sf/answers/3245392531/ (3认同)

dge*_*gel 69

您需要提供默认值:

new_field = models.CharField(max_length=140, default='SOME STRING')
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望首先使用虚假默认值进行迁移,然后创建[数据迁移](https://docs.djangoproject.com/en/1.7/topics/migrations/#data-migrations)以遍历每条记录并将`new_field`设置为`website`. (6认同)
  • 这并不能真正回答问题,因为问题明确指出“没有默认值”。 (3认同)

小智 31

一种选择是声明'new_field'的默认值:

new_field = models.CharField(max_length=140, default='DEFAULT VALUE')
Run Code Online (Sandbox Code Playgroud)

另一个选择是将'new_field'声明为可以为空的字段:

new_field = models.CharField(max_length=140, null=True)
Run Code Online (Sandbox Code Playgroud)

如果您决定接受'new_field'作为可空字段,您可能希望接受'无输入'作为'new_field'的有效输入.然后你还要添加blank=True语句:

new_field = models.CharField(max_length=140, blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)

即使使用null=True和/或blank=True您可以根据需要添加默认值:

new_field = models.CharField(max_length=140, default='DEFAULT VALUE', blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)

  • «避免在基于字符串的字段(如CharField和TextField)上使用null.如果基于字符串的字段具有null = True,则表示它有两个可能的值"无数据":NULL和空字符串.» - [模型字段引用](https://docs.djangoproject.com/en的/ dev/REF /模型/场/#空) (2认同)

Jus*_*nge 13

如果有人设置 a ForeignKey,您可以只允许可空字段而不设置默认值:

new_field = models.ForeignKey(model, null=True)
Run Code Online (Sandbox Code Playgroud)

如果您已经在数据库中存储了数据,您还可以设置一个默认值:

new_field = models.ForeignKey(model, default=<existing model id here>)
Run Code Online (Sandbox Code Playgroud)


Har*_*rsh 5

如果您处于开发周期的初期,可以尝试以下方法-

删除/注释该模型及其所有用法。应用迁移。这将删除该模型,然后再次添加模型,运行迁移,您将获得一个干净的模型,并添加了新字段。


小智 5

您不能添加对已包含数据的表的引用。
改变:

user = models.OneToOneField(User)
Run Code Online (Sandbox Code Playgroud)

到:

user = models.OneToOneField(User, default = "")
Run Code Online (Sandbox Code Playgroud)

做:

python manage.py makemigrations
python manage.py migrate
Run Code Online (Sandbox Code Playgroud)

再次改变:

user = models.OneToOneField(User)
Run Code Online (Sandbox Code Playgroud)

再次进行迁移:

python manage.py makemigrations
python manage.py migrate
Run Code Online (Sandbox Code Playgroud)


Dra*_*obZ 5

这是一种解决方法,无需做出妥协,例如删除所有现有数据/迁移(哎呀)、需要两次单独的迁移或设置不需要的默认值。采取以下步骤:

  1. 将新字段添加到您的模型中null=True
  2. python manage.py makemigrations <app_name> --name <migration_name>
  3. 将新字段更改为null=False
  4. python manage.py makemigrations <app_name>。在此步骤中,您将看到一个您以前可能从未见过的选项!您需要选项 2:“暂时忽略,让我自己处理带有 NULL 的现有行(例如,因为您在之前的数据迁移中添加了 RunPython 或 RunSQL 操作来处理 NULL 值)”在此输入图像描述
  5. migrations.AlterField操作从第二次迁移移至第一个迁移,并添加手动迁移来处理这些值NULL(如果不执行此步骤,您将像以前一样遇到完整性错误),如下所示:
def initial_display_names(apps, schema):
    Player = apps.get_model('my_app', 'Player')
    Player.objects.all().update(display_name='Cool Name')

def reversal(*args):
    """Reversal is NOOP since display_name is simply dropped during reverse"""


class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0049_foo'),
    ]

    operations = [
        migrations.AddField(
            model_name='player',
            name='display_name',
            field=models.CharField(help_text='name as shown in the UI', max_length=256, null=True),
        ),
        migrations.RunPython(initial_display_names, reversal),
        migrations.AlterField(
            model_name='player',
            name='display_name',
            field=models.CharField(help_text='name as shown in the UI', max_length=256),
        ),
    ]
Run Code Online (Sandbox Code Playgroud)
  1. 删除您所做的第二次迁移。
  2. python manage.py migrate <app_name>