1

我有两个模型:

class Profile(models.Model):
    # (...)
    settings = models.OneToOneField('Settings', null=True)
    # (...)

class Settings(model.Model):
    # (...)

有没有办法在访问Profile#settings时创建设置实例?

更新:我想要这个的主要动机是我已经有了Profile模型,并且我希望在用户点击需要Profile#setting实例的应用程序点时懒惰地创建Setting关系,而不关心它是否被创建或不。

更新: @miki725 在下面说这已经由 Django 处理。我尝试了以下方法:

class SettingsTest(TestCase):
    def setUp(self):
        user = User.objects.create(username='felipe', email='something@aol.com')
        self.profile = Profile.objects.create(short_name='Felipe', name='Felipe',
            user=user)

    def test_settings(self):
        self.assertIsNotNone(self.profile.settings)

我明白了:

Creating test database for alias 'default'...
F
======================================================================
FAIL: test_settings (activity.tests.settings.SettingsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/vagrant/activity/tests/settings.py", line 20, in test_settings
    self.assertIsNotNone(self.profile.settings)
AssertionError: unexpectedly None

----------------------------------------------------------------------
Ran 1 test in 0.003s
4

1 回答 1

1

这是由 Django 自动完成的!

>>> p = Profile.objects.get(...)
>>> isinstance(p.settings, Settings)
True

更新

如果您得到 None,这意味着模型中的外键值Profile为 null,因为您允许 null 值null=True。在这种情况下,你真的不能做任何事情:

>>> p = Profile(settings=None, ...)
>>> p.save()
>>> p = Profile.objects.get(pk=p.pk)
>>> p.settings # the settings can't be anything because you never assigned them
None

如果您需要这个进行测试,那么您必须为Profile实例分配一些设置值:

class SettingsTest(TestCase):
    def setUp(self):
        user = User.objects.create(username='felipe', email='something@aol.com')
        self.settings = Settings.objects.create(...)
        self.profile = Profile.objects.create(short_name='Felipe',
                                              name='Felipe',
                                              user=user,
                                              settings=self.settings)

顺便说一句,从 Django 1.5 开始,您可以配置您的用户模型。在您必须创建一个必须与用户模型具有一对一键的配置文件模型之前。现在不再需要了。您可以将字段添加到用户模型。您可以在 Django 1.5 发布文档 ( https://docs.djangoproject.com/en/dev/releases/1.5/#configurable-user-model )中阅读更多相关信息。

更新

现在您的动机更加清晰,您可以使用这种骇人听闻的方法来实现这一目标。我认为这不是最好的方法,但它应该有效:

Profile(models.Model):
    def get_default_settings(self):
        settings = Settings.objects.create(...)
        self.settings_id = settings.pk
        return settings

    def __getattribute__(self, name):
        default = object.__getattribute__(self, name)
        if name == 'settings':
            if default is None:
                return self.get_default_settings()
            else:
                return default
        else:
            return default
于 2013-03-20T04:04:38.217 回答