1

私は2つのモデルを持っています:

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

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

Profile#settingsにアクセスするたびにSettingsのインスタンスを作成する方法はありますか?

更新:これが必要な主な動機は、プロファイルモデルがすでにあり、ユーザーがProfile#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

アップデート

ProfileNoneを取得している場合は、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以降では、ユーザーモデルを構成できます。ユーザーモデルに対して1対1のキーが必要なプロファイルモデルを作成する前に。今ではそれはもう必要ありません。ユーザーモデルにフィールドを追加するだけです。これについて詳しくは、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 に答える