标签: factory-boy

Django 模型工厂获取或创建

我有一个 Django 模型,定义如下:

    class CustomModel(models.Model):
        column = models.CharField(max_length=50, unique=True)
Run Code Online (Sandbox Code Playgroud)

为模型定义工厂

from factory_boy import DjangoModelFactory
class CustomModelFactory(DjangoModelFactory):
    
    column = 'V1'

FACTORY_FOR = CustomModelFactory()
Run Code Online (Sandbox Code Playgroud)

我如何确保工厂每次都实现 get_or_create 而不是创建?

有谁知道如何做到这一点?

django django-models factory-boy

1
推荐指数
1
解决办法
3292
查看次数

在 django setUp() 单元测试中使用factory_boy时出现“StopIteration”异常

我有以下工厂:

class ContactFactory(DjangoModelFactory):
    name = Faker('company')
    industry = Iterator(Industry.objects.all())

    class Meta:
        model = 'sales.contact'

    @post_generation
        def requested_devices(self, create, extracted, **kwargs):
            if create:
              self.requested_devices.add(MSize.objects.first())
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个测试,例如:

class TestUserCanAskQuestion(TestCase):
    @classmethod
    def setUpTestData(cls):
        call_command('insert_initial_data')

    def setUp(self):
        self.contact = ContactFactory()
Run Code Online (Sandbox Code Playgroud)

但每次我运行测试时,都会导致“StopIteration”错误。这是完整的堆栈跟踪:

ERROR: test_dummy (comminquiry.tests.test_views.TestUserCanAskQuestion)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/mnt/c/Users/Alire/Projects/mm/mm-bpmui/src/comminquiry/tests/test_views.py", line 32, in test_dummy
    a = ContactFactory.build()
  File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/base.py", line 546, in build
    return cls._generate(enums.BUILD_STRATEGY, kwargs)
  File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/base.py", line 500, in _generate
    return step.build()
  File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/builder.py", line 272, in build
    step.resolve(pre)
  File "/mnt/c/Users/Alire/Projects/mm/venv/lib/python3.5/site-packages/factory/builder.py", …
Run Code Online (Sandbox Code Playgroud)

python django django-unittest factory-boy

1
推荐指数
1
解决办法
1203
查看次数

如何使用 Factory Boy 为模型字段生成随机数

我需要使用factory boy. 我有以下模型:

class Fabric(models.Model):
    title = models.CharField(max_length=200, blank=True)
    description = models.CharField(max_length=200, blank=True)
    price = models.DecimalField(decimal_places=2, max_digits=10, null=True, blank=False)
Run Code Online (Sandbox Code Playgroud)

我需要基于这个模型创建一个工厂,我希望价格在 1 到 100 之间有一个随机值。

class FabricFactory(DjangoModelFactory):
    class Meta:
        model = Fabric

    title = factory.Faker('name')
    description = factory.Faker('catch_phrase')
    price = random.randrange(MIN_PRICE, MAX_PRICE + 1)
Run Code Online (Sandbox Code Playgroud)

问题在于我总是为每个实例获得相同的价格。

python django factory-boy

1
推荐指数
2
解决办法
4422
查看次数

如何对 Django 模型强制执行 ManyToMany Blank=False 约束?

我正在使用 Django 3 和 Python 3.8。我有以下模型,请注意“类型”ManyToMany 字段,其中我将“空白”设置为 False。

class Coop(models.Model):
    objects = CoopManager()
    name = models.CharField(max_length=250, null=False)
    types = models.ManyToManyField(CoopType, blank=False)
    addresses = models.ManyToManyField(Address)
    enabled = models.BooleanField(default=True, null=False)
    phone = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_phone')
    email = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_email')
    web_site = models.TextField()
Run Code Online (Sandbox Code Playgroud)

我想验证如果将该字段留空会发生验证错误,所以我有

  @pytest.mark.django_db
    def test_coop_create_with_no_types(self):
        """ Verify can't create coop if no  """    
        coop = CoopFactory.create(types=[])
        self.assertIsNotNone(coop)
        self.assertNone( coop.id )
Run Code Online (Sandbox Code Playgroud)

并使用以下工厂(带有 FactoryBoy)来构建模型

class CoopFactory(factory.DjangoModelFactory):
    """
        Define Coop Factory
    """
    class Meta:
        model = Coop

    name = "test model" …
Run Code Online (Sandbox Code Playgroud)

django django-models django-validation python-3.x factory-boy

1
推荐指数
1
解决办法
2910
查看次数

如何根据父属性的条件生成子工厂

我有一个这样的工厂:

class PayInFactory(factory.DjangoModelFactory):
    class Meta:
        model = PayIn
  
    @factory.lazy_attribute
    def card(self):
        if self.booking_payment and self.booking_payment.payment_type in [bkg_cts.PAYMENT_CARD, bkg_cts.PAYMENT_CARD_2X]:
            factory.SubFactory(
                CardFactory,
                user=self.user,
            )
Run Code Online (Sandbox Code Playgroud)

card仅当该booking_payment字段具有payment_type以下值时,我才尝试生成该字段[bkg_cts.PAYMENT_CARD, bkg_cts.PAYMENT_CARD_2X]

代码进入该语句,但生成后卡字段为空。

我怎样才能正确地做到这一点?允许SubFactory进入吗lazy_attribute

如果可能的话,我希望能够从 PayInFactory 修改卡字段,如下所示:

>>> PayInFactory(card__user=some_user)
Run Code Online (Sandbox Code Playgroud)

PostGeneration不会这样做,因为我需要Card在调用创建之前使其可用。我覆盖了_create,它可能会使用该卡(如果可用)。

谢谢 !

factory-boy

1
推荐指数
1
解决办法
1166
查看次数

如何分配SubFactory的属性而不是SubFactory本身

我需要 SubFactory 的属性而不是它创建的对象。

# models.py
class User:
    pass

class UserProfile:
    user = models.OneToOneField(User)

class Job:
    user = models.ForeignKey(User)


# factories.py
class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = User

class UserProfileFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = UserProfile

    user = factory.SubFactory(UserFactory)

class JobFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Job

    # for certain reasons, I want to use UserProfileFactory here but get the user generated from it
    user = factory.SubFactory(UserProfileFactory).user  # doesn't work but you get the idea
Run Code Online (Sandbox Code Playgroud)

django factory-boy

1
推荐指数
1
解决办法
3025
查看次数

无法使用 factory-boy Django 进行身份验证

我对factory-boy陌生,我正在尝试向单元测试中的 API 端点发送请求,这需要对用户进行身份验证。端点需要在标头中以'Bearer ' + token. 我在网上查看了一些示例,这是我迄今为止在单元测试中提出的:

测试用户.py

class UserFactory(factory.Factory):
    class Meta:
        model = user

    username = factory.LazyAttribute(lambda t: "myuser")
    password = factory.PostGenerationMethodCall('set_password', 'my_super_secret')
    is_staff = True
    is_active = True

class UserViewSetTest(TestCase):
    def setUp(self):
        pwd = 'my_super_secret'
        self.user = UserFactory(password=pwd)
        self.client = Client()
        self.assertTrue(self.client.login(username=self.user.username, password=pwd))

    def test_user_list(self):
        response = self.client.get(reverse('user', kwargs={'fromdate': '2017-01-01', 'todate': '2017-04-01'})), format='json')
        self.assertEqual(response.status_code, 200)
Run Code Online (Sandbox Code Playgroud)

最初的错误是这个断言self.assertTrue(self.client.login(username=self.user.username, password=pwd))是错误的,因此测试立即失败。即使我删除了该行,API 调用也会返回 401,因为身份验证不成功。

如何使用 factory-boy 在此 API 调用中成功验证用户,以便我可以在 API 请求中发送令牌?我可以使用框架提供的用户模型吗?

编辑:

我试图创建一个令牌,以便将它传递给这样的标头:

def setUp(self): …
Run Code Online (Sandbox Code Playgroud)

django unit-testing django-unittest django-rest-framework factory-boy

1
推荐指数
1
解决办法
106
查看次数

Django工厂男孩在工厂中模拟模型方法

我的模型的保存方法是在保存后调用 api。为了测试我的应用程序,我使用DjangoModelFactory生成用于测试的对象。但是,api仍然被调用。

class MyClass(models.Model):
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        self.call_api()
Run Code Online (Sandbox Code Playgroud)

我尝试过模拟该方法,但它不起作用

#...
from .models import MyModel

@pytest.mark.django_db
@patch("MyModel.call_api")
class MyModelFactory(factory.django.DjangoModelFactory, factory.base.BaseFactory):
    class Meta:
        model = MyModel
Run Code Online (Sandbox Code Playgroud)

我的问题是,当我将它与工厂一起使用时,如何使用模拟方法?

django factory-boy

0
推荐指数
1
解决办法
1636
查看次数