Cor*_*son 4 python django inner-join django-models
我正在使用一个帐户模型,我想内部加入一个设置模型,而不必settings_id在我的帐户模型中创建一个额外的列,因为帐户表上的PK与设置表上的PK完全匹配.我一直在尝试在这些表和列之间建立OneToOne关系,但无法在不创建新列或其他内容的情况下弄清楚如何做到这一点.我正在尝试尽可能地使用现有模式,并且不希望创建不必要的列.
Class Account(models.Model):
login_id = models.AutoField(primary_key=True)
settings = models.OneToOneField('Settings', to_field='login_id', null=True,
related_name='settings', db_column='login_id') # Doesn't work because login_id already exists....
Class Settings(model.Model):
login_id = models.OneToOneField('Account', to_field='login_id', related_name='account')
Run Code Online (Sandbox Code Playgroud)
基本上,我试图复制的查询是:
SELECT * FROM account
INNER JOIN settings
ON account.login_id=settings.login_id
WHERE account.login_id=1
Run Code Online (Sandbox Code Playgroud)
根据错误,Django的ORM似乎在Account表中创建一个新列时非常持久,但是当两个表之间的关系如此简单时,我没有看到添加新列的重点: account.login_id = settings.login_id
虽然我自己从未尝试过,但将声明OneToOneField作为主键应该可行.
class Account(models.Model):
login_id = models.AutoField(primary_key=True)
class Settings(model.Model):
account = models.OneToOneField('Account', to_field='login_id',
primary_key=True, related_name='settings')
Run Code Online (Sandbox Code Playgroud)
声明这primary_key将使Django无法为您创建主键列,并且通过此设置您可以访问account.settings和settings.account或settings.account_id.
这是我最终做的:
class Account(models.Model):
login_id = models.AutoField(primary_key=True)
def get_settings_dict(self):
try:
return self.settings.to_dict()
except Settings.DoesNotExist:
return Settings.get_defaults_dict()
class Settings(model.Model):
account = models.OneToOneField('Account', to_field='login_id', related_name='settings')
# other settings properties
# other settings properties
def to_dict(self):
# return current values as dict
@staticmethod
def get_defaults_dict():
# return default values dict
Run Code Online (Sandbox Code Playgroud)
这使我可以访问用户的设置,account.settings而无需settings_id在 Account 模型上创建额外的列。两种模型都不需要 OneToOne 关系。
此外,get_settings_dict当用户的设置尚不存在时,该方法返回默认设置。这是一个很好的便利,可以防止我每次通过account.settings.