Django 模型与用户模型的关系
Django Models Relations to User Model
我是论坛的新手,遇到了问题。
我在 Django 中试图创建一个 UserProfile class,方法是通过 OnetoOneField 将其引用到用户对象。当我尝试迁移时,我得到:
“您正试图在没有默认值的情况下向作者添加不可为空的字段 'id';我们不能这样做(数据库需要一些东西来填充现有行)。
请 select 修复:
1) 现在提供一次性默认值(将在所有现有行上设置)
2) 退出,让我在 models.py"
中添加一个默认值
我明白,User 模型中的某些字段(例如 "id")不允许为空。
当我尝试设置默认值时,它会进行迁移,但迁移失败并出现语法错误。
我的问题是如何在不编写自定义用户的情况下允许 Null 或设置有效的默认值 class,这是否可能?
我非常感谢对此的任何帮助。
这是我的代码:
from django.db import models
from django.contrib.auth.models import User as User_django
class User(User_django):
pass
class Author(models.Model):
user = models.OneToOneField(User, null=True)
class BaseElement(models.Model):
author=models.ForeignKey(Author, null=True)
upvotes = models.PositiveIntegerField(default=0)
downvotes = models.PositiveIntegerField(default=0)
created = models.DateTimeField(auto_now_add=True, null=True)
def vote_up(self):
self.upvotes.value = self.upvotes.value + 1
def vote_down(self):
self.downvotes.value = self.downvotes.value + 1
class Meta:
abstract = True
class Post(BaseElement):
content = models.TextField(max_length=240)
tags = models.CharField(max_length=40, blank=True)
said_by = models.CharField(max_length=40)
said_at = models.CharField(max_length=40, blank=True)
def get_comments(self):
return self.comment_set.all()
def get_comments_anzahl(self):
return self.comment_set.all().count()
class Comment(BaseElement):
content = models.TextField(max_length=140)
commented_post = models.ForeignKey(Post, related_query_name="comment", null=True)
编辑:
如果我尝试设置默认值并尝试迁移,就会发生这种情况:
You are trying to add a non-nullable field 'id' to author 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)
2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can
do e.g. timezone.now()
>>> 1
Migrations for 'post':
0003_auto_20160505_1237.py:
- Change Meta options on author
- Change managers on author
- Remove field user_ptr from author
- Add field id to author
- Add field user to author
Operations to perform:
Apply all migrations: contenttypes, admin, sessions, post, auth
Running migrations:
Rendering model states... DONE
Applying post.0003_auto_20160505_1237...Traceback (most recent call last):
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: near ")": syntax error
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django /core/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 121, in database_forwards
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 247, in remove_field
self._remake_table(model, delete_fields=[field])
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 197, in _remake_table
self.quote_name(model._meta.db_table),
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 110, in execute
cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: near ")": syntax error
编辑:
好像我通过创建一个新项目并逐步复制模型和迁移来解决它。仍然想知道那里发生了什么,因为我刷新了数据库并多次删除了迁移文件,但它仍然抛出错误。
感谢您的帮助!
看看这个:
https://docs.djangoproject.com/es/1.9/topics/db/examples/one_to_one/
您的代码与用户是一对一的。当您设置它时,它意味着 CASCADE 删除,因此永远不能为空。
如果你改为一对多,只要确保你只为外键插入一个对象,它就会起作用。否则,请更改级联规则。
不过,我要说的是,这不是一个好主意,因为如果将其设为空,它与其他记录的区别是什么。考虑第二个 PK 字段。
祝你好运。
只需像这样导入 django 的内置 User
模型:
from django.contrib.auth.models import User
并删除此行:
class User(User_django):
pass
来自您的代码,因为它完全没有必要。
更新: 另外,您的问题似乎与 User
模型无关。我认为您以某种方式向 Author
模型添加了一个 id 字段并将其删除(可能是在迁移不成功之后)。如果是这种情况,那么您可以编辑 0003_auto_20160505_1237.py
。为此,请打开它并删除如下所示的行:
migrations.AddField(
model_name='author',
name='id',
field=models.someFieldType(options)),
),
然后重试。
我是论坛的新手,遇到了问题。
我在 Django 中试图创建一个 UserProfile class,方法是通过 OnetoOneField 将其引用到用户对象。当我尝试迁移时,我得到:
“您正试图在没有默认值的情况下向作者添加不可为空的字段 'id';我们不能这样做(数据库需要一些东西来填充现有行)。 请 select 修复: 1) 现在提供一次性默认值(将在所有现有行上设置) 2) 退出,让我在 models.py"
中添加一个默认值我明白,User 模型中的某些字段(例如 "id")不允许为空。
当我尝试设置默认值时,它会进行迁移,但迁移失败并出现语法错误。
我的问题是如何在不编写自定义用户的情况下允许 Null 或设置有效的默认值 class,这是否可能?
我非常感谢对此的任何帮助。
这是我的代码:
from django.db import models
from django.contrib.auth.models import User as User_django
class User(User_django):
pass
class Author(models.Model):
user = models.OneToOneField(User, null=True)
class BaseElement(models.Model):
author=models.ForeignKey(Author, null=True)
upvotes = models.PositiveIntegerField(default=0)
downvotes = models.PositiveIntegerField(default=0)
created = models.DateTimeField(auto_now_add=True, null=True)
def vote_up(self):
self.upvotes.value = self.upvotes.value + 1
def vote_down(self):
self.downvotes.value = self.downvotes.value + 1
class Meta:
abstract = True
class Post(BaseElement):
content = models.TextField(max_length=240)
tags = models.CharField(max_length=40, blank=True)
said_by = models.CharField(max_length=40)
said_at = models.CharField(max_length=40, blank=True)
def get_comments(self):
return self.comment_set.all()
def get_comments_anzahl(self):
return self.comment_set.all().count()
class Comment(BaseElement):
content = models.TextField(max_length=140)
commented_post = models.ForeignKey(Post, related_query_name="comment", null=True)
编辑:
如果我尝试设置默认值并尝试迁移,就会发生这种情况:
You are trying to add a non-nullable field 'id' to author 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)
2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can
do e.g. timezone.now()
>>> 1
Migrations for 'post':
0003_auto_20160505_1237.py:
- Change Meta options on author
- Change managers on author
- Remove field user_ptr from author
- Add field id to author
- Add field user to author
Operations to perform:
Apply all migrations: contenttypes, admin, sessions, post, auth
Running migrations:
Rendering model states... DONE
Applying post.0003_auto_20160505_1237...Traceback (most recent call last):
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: near ")": syntax error
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django /core/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 121, in database_forwards
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 247, in remove_field
self._remake_table(model, delete_fields=[field])
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 197, in _remake_table
self.quote_name(model._meta.db_table),
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 110, in execute
cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: near ")": syntax error
编辑: 好像我通过创建一个新项目并逐步复制模型和迁移来解决它。仍然想知道那里发生了什么,因为我刷新了数据库并多次删除了迁移文件,但它仍然抛出错误。
感谢您的帮助!
看看这个:
https://docs.djangoproject.com/es/1.9/topics/db/examples/one_to_one/
您的代码与用户是一对一的。当您设置它时,它意味着 CASCADE 删除,因此永远不能为空。
如果你改为一对多,只要确保你只为外键插入一个对象,它就会起作用。否则,请更改级联规则。
不过,我要说的是,这不是一个好主意,因为如果将其设为空,它与其他记录的区别是什么。考虑第二个 PK 字段。
祝你好运。
只需像这样导入 django 的内置 User
模型:
from django.contrib.auth.models import User
并删除此行:
class User(User_django):
pass
来自您的代码,因为它完全没有必要。
更新: 另外,您的问题似乎与 User
模型无关。我认为您以某种方式向 Author
模型添加了一个 id 字段并将其删除(可能是在迁移不成功之后)。如果是这种情况,那么您可以编辑 0003_auto_20160505_1237.py
。为此,请打开它并删除如下所示的行:
migrations.AddField(
model_name='author',
name='id',
field=models.someFieldType(options)),
),
然后重试。