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

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

Kev*_*nry 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')
Run Code Online (Sandbox Code Playgroud)

声明这primary_key将使Django无法为您创建主键列,并且通过此设置您可以访问account.settingssettings.accountsettings.account_id.


Cor*_*son 5

这是我最终做的:

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.