Django Model OneToOneField无需创建额外的_id数据库列

时间:2014-10-04 02:22:35

标签: python django django-models inner-join

我正在使用帐户模型,我希望内部加入设置模型,而不必在我的帐户模型中创建额外的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')

基本上,我试图复制的查询是:

SELECT * FROM account
INNER JOIN settings
ON account.login_id=settings.login_id
WHERE account.login_id=1

根据错误,Django的ORM似乎在Account表中创建一个新列时非常持久,但是当两个表之间的关系如此简单时,我没有看到添加新列的重点:{{1 }}

2 个答案:

答案 0 :(得分:7)

虽然我自己从未尝试过,但声明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')

声明primary_key会阻止Django为您创建主键列,通过此设置,您可以访问account.settingssettings.accountsettings.account_id。< / p>

答案 1 :(得分:4)

这是我最终做的事情:

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

这使我可以通过account.settings访问用户的设置,而无需在帐户模型上创建其他settings_id列。两种型号都不需要OneToOne关系。

此外,get_settings_dict方法在用户尚不存在设置时返回默认设置。这是一个很好的便利,使我无法在每次通过account.settings访问用户的设置时进行空检查。