8

Does anyone know how to create the factory in factoryboy based on this models.py

class Halte(models.Model):

    koppel_halte1 = models.ForeignKey('self',
                                  related_name='koppel_halteA',
                                  verbose_name="Koppel Halte",
                                  help_text="geef hier een gekoppelde halte aan",
                                  null=True, blank=True)

    koppel_halte2 = models.ForeignKey('self',
                                  related_name='koppel_halteB',
                                  verbose_name="Koppel Halte",
                                  help_text="geef hier een gekoppelde halte aan",
                                  null=True, blank=True)

Notice the 'self'? (And YES this type of relation is necesarry.)

I have tried several things in FactoryBoy (SubFactory, RelatedFactory, SelfAtribute, PostGeneration) but I can't get it to work.

one of the attempts in a factories.py

class HalteFactoryA(factory.DjangoModelFactory):
    class Meta:
        model = models.Halte


class HalteFactoryB(factory.DjangoModelFactory):
    class Meta:
        model = models.Halte


class HalteFactory(factory.DjangoModelFactory):
    class Meta:
        model = models.Halte
    # todo: how to do this?? (see models.Halte)
    koppel_halte1 = factory.RelatedFactory(HalteFactoryA)
    koppel_halte2 = factory.RelatedFactory(HalteFactoryB)

Any advice?

Thank you.

4

3 回答 3

9

@bakkal 基本上是正确的,但一个重要的缺失因素是必须指定目标递归深度,如本期所述: https ://github.com/rbarrois/factory_boy/issues/173

# myproj/myapp/factories.py
class MyModelFactory(factory.Factory):
    class Meta:
        model = models.MyModel
    parent = factory.SubFactory('myapp.factories.MyModelFactory')

然后需要添加递归最大深度,否则您会得到无限深度达到错误(如@Sjoerd van Poelgeest 在评论中指出的那样):

m = MyModelFactory(parent__parent__parent__parent=None)

在这种情况下,我们允许创建深度 3,并且最后一个将有一个空父级。

于 2016-08-03T16:51:57.527 回答
1

模型 FK 中的完全限定模型名称

为了使工具更容易自省模型,而不是'self',使用完全限定的模型名称:

koppel_halte1 = models.ForeignKey('yourapp.Halte', ...)
koppel_halte2 = models.ForeignKey('yourapp.Halte', ...)

请注意,它是一个字符串'yourapp.Halte',而不是yourapp.Halte.

SubFactory 中的完全限定工厂名称

如果您坚持在'self'模型中使用,您可以在您的模型中使用完全限定的模型名称SubFactory

# yourapp/factories.py

class HalteFactory(factory.Factory):
    class Meta:
        model = yourapp.Halte

    koppel_halte1 = factory.SubFactory('yourapp.factories.HalteFactory')
    koppel_halte2 = factory.SubFactory('yourapp.factories.HalteFactory')
于 2016-02-05T15:34:19.543 回答
0

我没能用 Factory Boy 修复它,但老式的设置确实有效。

然后我会(不情愿地)使用标准。

    class ModelHalteSelfTests(TestCase):
    def setUp(self):
        self.lijn1 = Lijn.objects.create(id=1, nummer=1, techniek=GlobalWaardes.TECHNIEK_BUS)
        self.lijn2 = Lijn.objects.create(id=2, nummer=2, techniek=GlobalWaardes.TECHNIEK_TRAM)

        self.halte1 = Halte.objects.create(id=1, nummer=100, aantal_vitrinekasten=2, aantal_hpkasten=0)
        self.halte2 = Halte.objects.create(id=2, nummer=200, aantal_vitrinekasten=1, aantal_hpkasten=1)
        self.halte3 = Halte.objects.create(id=3, nummer=300, aantal_vitrinekasten=0, aantal_hpkasten=3)
        self.halte4 = Halte.objects.create(id=4, koppel_halte1=self.halte1, koppel_halte2=self.halte2)

        self.halteregel1 = Halteregel.objects.create(id=1, lijn=self.lijn1, halte=self.halte1, volgorde=10)
        self.halteregel2 = Halteregel.objects.create(id=2, lijn=self.lijn1, halte=self.halte2, volgorde=20)
        self.halteregel3 = Halteregel.objects.create(id=3, lijn=self.lijn2, halte=self.halte2, volgorde=20)
        self.halteregel4 = Halteregel.objects.create(id=4, lijn=self.lijn2, halte=self.halte3, volgorde=10)

    def test_lijst_halteregels(self):
        self.assertEqual(self.halte1.lijst_halteregels(), [self.halteregel1])
        self.assertEqual(self.halte2.lijst_halteregels(), [self.halteregel2, self.halteregel3])
        self.assertEqual(self.halte3.lijst_halteregels(), [self.halteregel4])
        self.assertEqual(self.halte4.lijst_halteregels(), [self.halteregel1, self.halteregel2, self.halteregel3])
于 2016-02-11T10:13:27.810 回答