为什么 Django 的工厂男孩在我没有要求的时候试图创建一个工厂?
Why is Django's factory-boy trying to create a factory when I'm not asking it to?
我正在尝试使用 Django 的 factory-bot 模块为我的模型创建工厂。我也在使用 pytest。我创建了这些工厂 ...
import factory
from maps.models import CoopType, Coop
from address.models import AddressField
from phonenumber_field.modelfields import PhoneNumberField
from address.models import State, Country, Locality
class CountryFactory(factory.DjangoModelFactory):
"""
Define Country Factory
"""
class Meta:
model = Country
name = "Narnia"
code = "NN"
class StateFactory(factory.DjangoModelFactory):
"""
Define State Factory
"""
class Meta:
model = State
name = "Narnia"
code = "NN"
country = CountryFactory()
class LocalityFactory(factory.DjangoModelFactory):
"""
Define Locality Factory
"""
class Meta:
model = Locality
name = "Narnia"
postal_code = "60605"
state = StateFactory()
class AddressFactory(factory.DjangoModelFactory):
"""
Define Address Factory
"""
class Meta:
model = Address
street_number = "123"
route = "Rd"
raw = "123 Fake Rd"
formatted = "123 Fake Rd."
latitude = 87.1234
longitude = -100.12342
locality = LocalityFactory()
class CoopTypeFactory(factory.DjangoModelFactory):
"""
Define Coop Type Factory
"""
class Meta:
model = CoopType
到目前为止,我有一个非常简单的测试文件。它只有一个测试...
import pytest
from django.test import TestCase
from .factories import CoopTypeFactory, CoopFactory
class ModelTests(TestCase):
@classmethod
def setUpTestData(cls):
print("setUpTestData: Run once to set up non-modified data for all class methods.")
#management.call_command('loaddata', 'test_data.yaml', verbosity=0)
pass
def setUp(self):
print("setUp: Run once for every test method to setup clean data.")
#management.call_command('flush', verbosity=0, interactive=False)
pass
@pytest.mark.django_db
def test_coop_type_create(self):
""" Test customer model """ # create customer model instance
coop_type = CoopTypeFactory(name="Test Coop Type Name")
assert coop_type.name == "Test Coop Type Name"
但是当我 运行 我的测试时,它死于抱怨我什至没有创建的工厂的重复密钥。
davea$ python manage.py test --settings=maps.test_settings
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: tests.test_models (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: tests.test_models
Traceback (most recent call last):
File "/Users/davea/Documents/workspace/chicommons/maps/web
...
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/loader.py", line 434, in _find_test_path
module = self._get_module_from_name(name)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/loader.py", line 375, in _get_module_from_name
__import__(name)
File "/Users/davea/Documents/workspace/chicommons/maps/web/tests/test_models.py", line 3, in <module>
from .factories import CoopTypeFactory, CoopFactory
File "/Users/davea/Documents/workspace/chicommons/maps/web/tests/factories.py", line 19, in <module>
class StateFactory(factory.DjangoModelFactory):
File "/Users/davea/Documents/workspace/chicommons/maps/web/tests/factories.py", line 28, in StateFactory
country = CountryFactory()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 46, in __call__
return cls.create(**kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 564, in create
return cls._generate(enums.CREATE_STRATEGY, kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/django.py", line 141, in _generate
return super(DjangoModelFactory, cls)._generate(strategy, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 501, in _generate
return step.build()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/builder.py", line 279, in build
kwargs=kwargs,
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 315, in instantiate
return self.factory._create(model, *args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/django.py", line 185, in _create
return manager.create(*args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 417, in create
obj.save(force_insert=True, using=self.db)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 729, in save
force_update=force_update, update_fields=update_fields)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 759, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 842, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 880, in _do_insert
using=using, raw=raw)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 1125, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1280, in execute_sql
cursor.execute(sql, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 71, in execute
return self.cursor.execute(query, args)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/MySQLdb/cursors.py", line 209, in execute
res = self._query(query)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/MySQLdb/cursors.py", line 315, in _query
db.query(q)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/MySQLdb/connections.py", line 239, in query
_mysql.connection.query(self, query)
django.db.utils.IntegrityError: (1062, "Duplicate entry 'Narnia' for key 'name'")
----------------------------------------------------------------------
Ran 1 test in 0.000s
我做错了什么?为什么 Django 试图为我没有为其创建工厂的东西创建工厂?
您应该使用 factory.SubFactory
来定义外键关系
class LocalityFactory(factory.DjangoModelFactory):
...
state = factory.SubFactory(StateFactory)
调用您 类 中的工厂正在创建实例
我正在尝试使用 Django 的 factory-bot 模块为我的模型创建工厂。我也在使用 pytest。我创建了这些工厂 ...
import factory
from maps.models import CoopType, Coop
from address.models import AddressField
from phonenumber_field.modelfields import PhoneNumberField
from address.models import State, Country, Locality
class CountryFactory(factory.DjangoModelFactory):
"""
Define Country Factory
"""
class Meta:
model = Country
name = "Narnia"
code = "NN"
class StateFactory(factory.DjangoModelFactory):
"""
Define State Factory
"""
class Meta:
model = State
name = "Narnia"
code = "NN"
country = CountryFactory()
class LocalityFactory(factory.DjangoModelFactory):
"""
Define Locality Factory
"""
class Meta:
model = Locality
name = "Narnia"
postal_code = "60605"
state = StateFactory()
class AddressFactory(factory.DjangoModelFactory):
"""
Define Address Factory
"""
class Meta:
model = Address
street_number = "123"
route = "Rd"
raw = "123 Fake Rd"
formatted = "123 Fake Rd."
latitude = 87.1234
longitude = -100.12342
locality = LocalityFactory()
class CoopTypeFactory(factory.DjangoModelFactory):
"""
Define Coop Type Factory
"""
class Meta:
model = CoopType
到目前为止,我有一个非常简单的测试文件。它只有一个测试...
import pytest
from django.test import TestCase
from .factories import CoopTypeFactory, CoopFactory
class ModelTests(TestCase):
@classmethod
def setUpTestData(cls):
print("setUpTestData: Run once to set up non-modified data for all class methods.")
#management.call_command('loaddata', 'test_data.yaml', verbosity=0)
pass
def setUp(self):
print("setUp: Run once for every test method to setup clean data.")
#management.call_command('flush', verbosity=0, interactive=False)
pass
@pytest.mark.django_db
def test_coop_type_create(self):
""" Test customer model """ # create customer model instance
coop_type = CoopTypeFactory(name="Test Coop Type Name")
assert coop_type.name == "Test Coop Type Name"
但是当我 运行 我的测试时,它死于抱怨我什至没有创建的工厂的重复密钥。
davea$ python manage.py test --settings=maps.test_settings
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: tests.test_models (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: tests.test_models
Traceback (most recent call last):
File "/Users/davea/Documents/workspace/chicommons/maps/web
...
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/loader.py", line 434, in _find_test_path
module = self._get_module_from_name(name)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/loader.py", line 375, in _get_module_from_name
__import__(name)
File "/Users/davea/Documents/workspace/chicommons/maps/web/tests/test_models.py", line 3, in <module>
from .factories import CoopTypeFactory, CoopFactory
File "/Users/davea/Documents/workspace/chicommons/maps/web/tests/factories.py", line 19, in <module>
class StateFactory(factory.DjangoModelFactory):
File "/Users/davea/Documents/workspace/chicommons/maps/web/tests/factories.py", line 28, in StateFactory
country = CountryFactory()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 46, in __call__
return cls.create(**kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 564, in create
return cls._generate(enums.CREATE_STRATEGY, kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/django.py", line 141, in _generate
return super(DjangoModelFactory, cls)._generate(strategy, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 501, in _generate
return step.build()
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/builder.py", line 279, in build
kwargs=kwargs,
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/base.py", line 315, in instantiate
return self.factory._create(model, *args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/factory/django.py", line 185, in _create
return manager.create(*args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 417, in create
obj.save(force_insert=True, using=self.db)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 729, in save
force_update=force_update, update_fields=update_fields)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 759, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 842, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/base.py", line 880, in _do_insert
using=using, raw=raw)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 1125, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1280, in execute_sql
cursor.execute(sql, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 71, in execute
return self.cursor.execute(query, args)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/MySQLdb/cursors.py", line 209, in execute
res = self._query(query)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/MySQLdb/cursors.py", line 315, in _query
db.query(q)
File "/Users/davea/Documents/workspace/chicommons/maps/web/venv/lib/python3.7/site-packages/MySQLdb/connections.py", line 239, in query
_mysql.connection.query(self, query)
django.db.utils.IntegrityError: (1062, "Duplicate entry 'Narnia' for key 'name'")
----------------------------------------------------------------------
Ran 1 test in 0.000s
我做错了什么?为什么 Django 试图为我没有为其创建工厂的东西创建工厂?
您应该使用 factory.SubFactory
来定义外键关系
class LocalityFactory(factory.DjangoModelFactory):
...
state = factory.SubFactory(StateFactory)
调用您 类 中的工厂正在创建实例