【发布时间】:2019-06-10 18:30:36
【问题描述】:
我有一个用于 Users 的 Django 模型,然后是一个用于 AccessLevels 的独立模型。
当使用 Django 的 ORM 保存 User 时,我还想在 AccessLevels 表中放置一个条目。
我的问题是 AccessLevels 的 PK 是 Users 的 PK,我似乎无法覆盖save() 方法并收集id = models.AutoField(primary_key=True) 的值。
这是我的相关代码:
class Users(models.Model):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# pk
id = models.AutoField(primary_key=True)
# client_id
client_id = models.IntegerField(null=False, blank=False, default="-1")
...
def save(self, *args, **kwargs):
AccessLevel(user_id=self.id,
client_id=self.client_id).save(using='default')
print('Access Level Set for User while saving')
super(Users, self).save(*args, **kwargs)
这是AccessLevel
的重要部分class AccessLevel(models.Model):
# pk
id = models.AutoField(primary_key=True)
# this is the id for the user, but I get null value
user_id = models.IntegerField(null=False, blank=False, default="-1")
client_id = models.IntegerField(null=False, blank=False, default="-1")
当我调用此代码时,我得到了错误。
root_user = Users(username='root',
email='root',
first_name='root',
last_name='root',
phone='root',
password=make_password(default_root_pw),
type='root').save(using='default')
这是错误
django.db.utils.IntegrityError:“user_id”列中的空值违反非空约束 详细信息:失败行包含 (3, null, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)。强>
【问题讨论】:
-
不要那样做!主键通常被视为“黑盒”。是的,这些是数字,但旨在协调两个主键确实是在找麻烦。此外,“分发”主键的不是 Django,而是数据库本身。这保证了分发的主键是唯一的(当然,除非数据库有问题)。
-
此外,您应该使用
ForeignKeys 来关联另一个对象,而不是IntegerFields。ForeignKeys 将为数据库添加额外的约束,以保证此类列中的值始终引用具有此类主键的(现有)记录。 -
不,这会导致更严重的反模式:数据重复。最好使用
ForeignKeys。 Django 还为此为程序员提供了便利,因为您相关的对象是延迟加载到内存中的。
标签: python django django-models model