7

2 つ以上のモデルが共通の外部キーを持ち、同じものを持つべきときにそれぞれが独自のオブジェクトを作成すると、工場で問題が発生し続けます。

問題を説明するために、簡略化したモデル構造を次に示します。

class Language (models.Model):
    code = models.CharField(max_length=3, unique=True)


class Audio(models.Model):
    language = models.ForeignKey(Language)
    soundfile = models.FileField()


class Subtitles(models.Model):
    language = models.ForeignKey(Language)
    text = models.TextField()


class Recording(models.Model):
    audio = models.ForeignKey(Audio)
    subtitles = models.ForeignKey(Subtitles)

したがって、 aRecordingにはAudioと があり、両方とも各言語コードに固有の をSubtitles持っています。Language

この構造のファクトリは次のとおりです。

class LanguageFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Language


class AudioFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Audio

    language = factory.SubFactory(LanguageFactory, code='en1')


class SubtitlesFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Subtitles

    language = factory.SubFactory(LanguageFactory, code='en1')


class RecordingFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Recording

    audio = factory.SubFactory(AudioFactory)
    subtitles = factory.SubFactory(SubtitlesFactory)

音声と字幕が同じ言語であることは非常に一般的なケースです。通常、それは単なる書き起こしであるためです。したがって、上記のファクトリに反映されているように、デフォルトの RecordingFactory に、コードとして「en1」の言語のオーディオと字幕が必要です。

しかし、各ファクトリは言語の独自のインスタンスを作成しようとするため、RecordingFactory をインスタンス化するとrecording = RecordingFactory()(私はよくこれを行います)、例外が発生します。

IntegrityError: UNIQUE constraint failed: recordings_language.code

それを解決するには、次のようなことができます。

language = LanguageFactory(code='en1')
recording = RecordingFactory(subtitles__language=language, audio__language=language)

しかし、それは冗長です。私の実際のプロジェクトでは、さらに多くのつながりがあるため、言語を 3 ~ 4 か所、場合によっては 4 レベルの深さで指定する必要があります。代わりに、既に存在する場合に作成または使用されるデフォルトを指定できるようにしたいと考えています。

存在する場合、これを回避する正しい方法は何ですか?

4

2 に答える 2

5

オプションを使用できParamsます ( http://factoryboy.readthedocs.io/en/latest/reference.html#parameters ):

class RecordingFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Recording

    class Params:
        language = factory.SubFactory(Language)

    subtitles = factory.SubFactory(SubtitlesFactory, 
        language=factory.SelfAttribute('language'))
    audio = factory.SubFactory(AudioFactory, 
        language=factory.SelfAttribute('language'))
于 2016-09-06T09:49:03.740 に答える