我有两种模式:
class Profile(models.Model):
# (...)
settings = models.OneToOneField('Settings', null=True)
# (...)
class Settings(model.Model):
# (...)
是否有办法在访问个人资料#设置时创建设置的实例?
更新:我想要这样做的主要动机是我已经拥有个人资料模型,我希望设置关系可以懒惰地创建当用户点击需要个人资料#设置实例的应用点时,无需关心是否已创建。
更新: @ 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
答案 0 :(得分:1)
由Django自动完成!
>>> p = Profile.objects.get(...)
>>> isinstance(p.settings, Settings)
True
<强>更新强>
如果您收到None,则表示Profile
模型中的外键值为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)中阅读更多相关信息。
<强>更新强>
现在您的动机更加明确,您可以使用这种hackish方法实现这一目标。我不认为这是最好的方法,但它应该有效:
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