0

私はfunctionいくつかのを持っておりparameters、次にその関数の特殊化を行い、関数のパラメータごとにinstantiationいくつかを持っています。settingsだから私は次のような構造を持っています:

class Function(models.Model):
    name = models.CharField()

class FunctionParameter(models.Model):
    function = models.ForeignKey(Function)

class FunctionInstantiation(models.Model):
    function = models.ForeignKey(Function)

class ParameterSetting(models.Model):
    function_instantiation = models.ForeignKey(FunctionInstantiation)
    function_parameter = models.ForeignKey(FunctionParameter)

を作成するために使用FunctionFactoryできます。factory.RelatedFactoryparameters

しかし、内で作成されたオブジェクトにアクセスできないため、 をFunctionInstantiationFactory使用factory.RelatedFactory(ParameterSetting)して作成することはできず、 を設定できません。ParameterSettingsparameterFunctionFactoryparameter_setting.function_parameter_id

で作成されたパラメータをFunctionInstantiationFactory検索するにはどうすればよいですか? の戻り値からそれらを取得できますか? または、データベースを確認する必要がありますか?parameter_idFunctionFactoryRelatedFactory(FunctionFactory)

4

2 に答える 2

0

これは Xelnor の回答ですが、 /ペアfunction_instantiationごとに 1 つではなく、1つだけが作成されるようにバグを修正します。parameterparameter_setting

class FunctionFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Function
    name = factory.Sequence(lambda n: "Function %d" % n)


class FunctionParameterFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.FunctionParameter
    function = factory.SubFactory(FunctionFactory)


class FunctionInstantiationFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.FunctionInstantiation
    function = factory.SubFactory(FunctionFactory)


class ParameterSettingFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.ParameterSetting

    function_instantiation = factory.SubFactory(FunctionInstantiationFactory)
    function_parameter = factory.SubFactory(FunctionParameterFactory,
        function=factory.SelfAttribute('..function_instantiation.function'))


class FunctionToParameterSettingsFactory(FunctionInstantiationFactory):
    class Meta:
        model = models.FunctionInstantiation

    # This overrides the function_instantiation created inside
    # ParameterSettingFactory, which then overrides the Function creation,
    # with the SelfAttribute('..function_instantiation.function') syntax.
    parameter_setting_1 = factory.RelatedFactory(ParameterSettingFactory, 
        'function_instantiation')
    parameter_setting_2 = factory.RelatedFactory(ParameterSettingFactory, 
        'function_instantiation')

以下は、関連するオブジェクトの値のオーバーライドや、それ自体がリンクされている他のテーブルへのリンクなど、このパターンを使用するすべての人がおそらく遭遇する可能性のある他のいくつかの問題の解決策を示しています。それは主に、Xelnor が彼の回答で紹介したテクニックに基づいています。

class FunctionFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Function
    name = factory.Sequence(lambda n: "Function %d" % n)


class FunctionParameterFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.FunctionParameter
    name = factory.Sequence(lambda n: "Function %d" % n)
    function = factory.SubFactory(FunctionFactory)


class ParameterSettingFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.ParameterSetting
    name = factory.Sequence(lambda n: "Function %d" % n)

    function_instantiation = factory.SubFactory(FunctionInstantiationFactory)
    function_parameter = factory.SubFactory(FunctionParameterFactory,
        function=factory.SelfAttribute('..function_instantiation.function'))


class DatasetAnd2ColumnsFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Function
    dataset = factory.SubFactory(DatasetFactory,
        name=factory.Sequence(lambda n: "Custom dataset %d" % n))
    column_1 = factory.SubFactory(ColumnFactory, dataset=dataset,
        name=factory.Sequence(lambda n: "Column 1 %d" % n))
    column_2 = factory.SubFactory(ColumnFactory, dataset=dataset,
        name=factory.Sequence(lambda n: "Column 2 %d" % n))


# I found it neater not to inherit in the end, due to needing quite a lot of
# additional complexity not included in my original question.
class FunctionToParameterSettingsFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.FunctionInstantiation

    name = factory.Sequence(lambda n: "Custom instantiation name %d" % n)
    # You can call Sequence to pass values to SubFactories
    function = factory.SubFactory(FunctionFactory, 
        name=factory.Sequence(lambda n: "Custom function %d" % n))

    parameter_setting_1 = factory.RelatedFactory(ParameterSettingFactory, 
        'function_instantiation',
        # Note the __ syntax for override values for nested objects:
        parameter__name='Parameter 1',
        name='Parameter Setting 1')
    # Possible to use Sequence here too, and makes looking at data easier
    parameter_setting_2 = factory.RelatedFactory(ParameterSettingFactory, 
        'function_instantiation',
        parameter__name=factory.Sequence(lambda n: "Param 1 for fn %d" % n),
        name=factory.Sequence(lambda n: "Param Setting 1 for fn %d" % n))

ここで、いくつかのデータ列を含むデータセットを作成し、parameter_setting レコードをそれらの列と結合する必要があります。そうするために、これは の最後に行きますFunctionToParameterSettingsFactory:

@factory.post_generation
def post(self, create, extracted, **kwargs):
    if not create:
         return

    dataset = DatasetAnd2ColumnsFactory()
    column_ids_by_name = 
        dict((column.name, column.id) for column in dataset.column_set.all())

    # self is the `FunctioInstantiation` Django object just created by the `FunctionToParameterSettingsFactory`
    for parameter_setting in self.parametersetting_set.all():
        if parameter_setting.name == 'age_in':
            parameter_setting.column_id = column_ids_by_name['Age']
            parameter_setting.save()
        elif parameter_setting.name == 'income_in':
            parameter_setting.column_id = column_ids_by_name['Income']
            parameter_setting.save()

これは確かに少しハックです。column=column_1RelatedFactory 呼び出しを渡そうとしましたが、それによって複数のデータセットが作成され、各列が別の列にリンクされました。SelfAttribute と LazyAttribute であらゆる種類のアクロバットを試しましたが、どちらも RelatedFactory 呼び出しでは使用できず、SubFactory(SelfAttribute()) で何かを作成してから RelatedFactory に渡すことはできません。私の他の質問)。

私の実際のコードでは、データセットへの外部キーを持つモデルがさらにいくつかあり、すべてうまく結び付けられました。

于 2015-10-09T16:47:03.160 に答える