Python 您正在尝试添加不可为空的字段';新字段';在没有默认设置的情况下创建userprofile
我知道,从Django 1.7开始,我不需要使用South或任何其他迁移系统,所以我只需要使用简单的命令Python 您正在尝试添加不可为空的字段';新字段';在没有默认设置的情况下创建userprofile,python,django,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 exi
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).
下面是models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User)
website = models.URLField(blank=True)
new_field = models.CharField(max_length=140)
有哪些选项?您需要提供默认值:
new_field = models.CharField(max_length=140, default='SOME STRING')
new_field = models.ForeignKey(model, default=<existing model id here>)
如果“网站”可以为空,则new_字段
也应设置为空
现在,如果要在保存时添加逻辑,其中ifnew\u字段为空,则要从“website”中获取值,只需覆盖模型的保存功能,如下所示:
class UserProfile(models.Model):
user = models.OneToOneField(User)
website = models.URLField(blank=True, default='DEFAULT VALUE')
new_field = models.CharField(max_length=140, blank=True, default='DEFAULT VALUE')
def save(self, *args, **kwargs):
if not self.new_field:
# Setting the value of new_field with website's value
self.new_field = self.website
# Saving the object with the default save() function
super(UserProfile, self).save(*args, **kwargs)
# please keep in mind that new_value can be an empty string. You decide whether it is a correct value.
for profile in UserProfile.objects.filter(new_value__isnull=True).iterator():
profile.new_value = calculate_value(profile)
profile.save() # better to use batch save
一个选项是为“new_field”声明默认值:
new_field = models.CharField(max_length=140, default='DEFAULT VALUE')
另一个选项是将“new_field”声明为可为空的字段:
new_field = models.CharField(max_length=140, null=True)
如果您决定接受“new_field”作为可空字段,您可能希望接受“no input”作为“new_field”的有效输入。然后还必须添加blank=True
语句:
new_field = models.CharField(max_length=140, blank=True, null=True)
即使使用null=True
和/或blank=True
也可以在必要时添加默认值:
new_field = models.CharField(max_length=140, default='DEFAULT VALUE', blank=True, null=True)
在新文件中添加布尔属性null
new_field = models.CharField(max_length=140, null=True)
运行刷新数据库的/manage.py syncdb
后。
最后运行/manage.py makemigrations
和/manage.py migrate
如果您处于早期开发周期,并且不关心当前数据库数据,您可以将其删除,然后进行迁移。但首先需要清除migrations dir并从表中删除它的行(django_migrations)
注意:不要删除migrations文件夹中的y.py
rm db.sqlite3
python manage.py makemigrations
python manage.py migrate
如果您以前为Django的管理web应用程序创建了超级用户,则可能需要再次创建该用户。表UserProfile
中是否已有数据库条目?如果是这样,当您添加新列时,DB不知道将其设置为什么,因为它不能为NULL
。因此,它会询问您希望将列new\u fields
中的字段设置为什么。我必须删除此表中的所有行以解决此问题
(我知道这个问题不久前已经得到了回答,但我刚刚遇到了这个问题,这是我的解决方案。希望它能帮助任何看到这个问题的新手)您可以在此页面使用Django Doc中的方法
创建默认值并使用它
def contact_default():
return {"email": "to1@example.com"}
contact_info = JSONField("ContactInfo", default=contact_default)
如果您处于开发周期的早期,您可以尝试以下方法-
删除/注释该模型及其所有用法。应用迁移。这将删除该模型,然后再次添加该模型,运行迁移,您就有了一个干净的模型,并添加了新字段。Django实际上说的是:
Userprofile表中有数据,可能有新字段
值
它们是空的,但我不知道,所以您确定要标记吗
属性设置为不可为null,因为如果这样做,则在
有空值
如果您确定userprofile
表中的任何值都不为空,则忽略该警告
这种情况下的最佳实践是创建RunPython迁移,以处理选项2中所述的空值
2) 暂时忽略,让我自己用NULL处理现有行(例如,因为您在以前的数据迁移中添加了RunPython或RunSQL操作来处理NULL值)
在RunPython迁移中,您必须找到所有UserProfile
实例的new_字段为空
值,并在那里输入正确的值(或Django要求您在模型中设置的默认值)。
你会得到这样的结果:
class UserProfile(models.Model):
user = models.OneToOneField(User)
website = models.URLField(blank=True, default='DEFAULT VALUE')
new_field = models.CharField(max_length=140, blank=True, default='DEFAULT VALUE')
def save(self, *args, **kwargs):
if not self.new_field:
# Setting the value of new_field with website's value
self.new_field = self.website
# Saving the object with the default save() function
super(UserProfile, self).save(*args, **kwargs)
# please keep in mind that new_value can be an empty string. You decide whether it is a correct value.
for profile in UserProfile.objects.filter(new_value__isnull=True).iterator():
profile.new_value = calculate_value(profile)
profile.save() # better to use batch save
玩得开心 老实说,解决这个问题的最佳方法是创建另一个模型,其中包含您需要的所有字段,并且名称略有不同。运行迁移。删除未使用的模型并再次运行迁移。瞧。如果SSH为您提供了两个选项,请选择数字1,然后输入“无”。只是……目前。您不能添加对已包含数据的表的引用。
更改:
致:
做:
再次更改:
user = models.OneToOneField(User)
再次执行迁移:
python manage.py makemigrations
python manage.py migrate
如果可以截断相关模型的表,可以在提示中指定一个一次性默认值None
。迁移将有多余的default=None
,而您的代码没有默认值。可以很好地应用它,因为表中不再有需要默认值的数据。在models.py中
类用户配置文件(models.Model):
用户=模型。OneToOneField(用户)
website=models.URLField(blank=True)
新建字段=models.CharField(最大长度=140,默认值=“某些值”)
您需要添加一些值作为默认值 我处于开发周期的早期,所以这可能不适合所有人(但我不明白为什么不适合)
我在获取错误的列中添加了blank=True,null=True
。然后我运行了python manage.py makemigrations
命令
在运行此命令之后(以及在运行python manage.py migrate
之前),我立即从所有列中删除了blank=True、null=True
。然后我再次运行了python manage.py makemigrations
。我可以选择自己更改列,我选择了这个选项
然后我运行了python manage.py migrate
,一切正常 如果有人正在设置外键
,您可以只允许可为空的字段,而不设置默认值:
new_field = models.ForeignKey(model, null=True)
如果数据库中已存储数据,还可以设置默认值:
new_field = models.CharField(max_length=140, default='SOME STRING')
new_field = models.ForeignKey(model, default=<existing model id here>)
new\u field=models.ForeignKey(model,default=)
基本上我解决了这个问题,将null=True
放在添加的模型中。
例如:
我试图在现有的数据库模块中添加电话号码
phone_number = models.CharField(max_length=10)
我以前得了t
phone_number = models.CharField(max_length=10, null=True)
python manage.py makemigrations
Migrations for 'collegekhajagharapp':
collegekhajagharapp\migrations\0002_customer_phone_number.py
- Add field phone_number to customer