[英]Factory_boy not creating different User objects Django
I am new to Factory_boy with Django. After spending some time I understood how to create a factory for User model.我是 Django 的 Factory_boy 新手。花了一些时间后,我了解了如何为用户 model 创建工厂。
I am using the default user model and following is my factory.我使用默认用户 model 以下是我的工厂。 I am using Faker for randomness
我使用 Faker 来实现随机性
import factory
from . import models
from django.contrib.auth.models import User
from faker import Faker
from django.contrib.auth.hashers import make_password
fake = Faker()
class UserFactory(factory.DjangoModelFactory):
class Meta:
model = User
django_get_or_create = ('email',)
first_name = fake.first_name()
last_name = fake.last_name()
email = first_name+"."+last_name+"@gmail.com"
password = make_password("ojasojas")
username = first_name+"_"+last_name
Now in the django shell现在在 django shell
I use UserFactory.create() to crate an user.我使用 UserFactory.create() 来创建一个用户。 this works fine.
这很好用。 Is it possible to loop through create statement and crate 5 different users?
是否可以循环创建语句并创建 5 个不同的用户? Now when I am doing that I am getting only one user (crated once and 'get' 4 times) as follows.
现在,当我这样做时,我只获得了一个用户(装箱一次并“获得”4 次),如下所示。 What am I missing?
我错过了什么?
You are defining class attributes for your factory, which get evaluated only when the class is defined.您正在为您的工厂定义 class 属性,只有在定义 class 时才会评估这些属性。
email = first_name+"."+last_name+"@gmail.com"
will be evaluated once, not each time you call UserFactory.create()
, hence the unique constraint errors. email = first_name+"."+last_name+"@gmail.com"
将被评估一次,而不是每次调用UserFactory.create()
时,因此唯一约束错误。 The usual solution to this is to instead define instance attributes via __init__()
, but FactoryBoy has their own solution to this: lazy attributes .通常的解决方案是通过
__init__()
定义实例属性,但 FactoryBoy 对此有自己的解决方案:惰性属性。
This may not be the best solution, but its a work around I've been using lately.这可能不是最好的解决方案,但它是我最近一直在使用的解决方法。 I set the following Global:
我设置了以下全局:
NAMES = [factory.Faker('name')._get_faker().name() for i in range(5)]
In this case, the above will generate a list of 5 fake names.在这种情况下,上面将生成一个包含 5 个假名的列表。
NOTE: this does not guarantee a unique name (as FuzzyChoice
will just select one from the list).注意:这不保证唯一的名称(因为
FuzzyChoice
只会从列表中选出一个 select)。
and within your factory:在您的工厂内:
name = factory.LazyAttribute(lambda obj: factory.fuzzy.FuzzyChoice(NAMES).fuzz())
FactoryBoy offers LazyFunction
and LazyAttribute
classes to achieve this. FactoryBoy 提供了
LazyFunction
和LazyAttribute
类来实现这一点。 Difference between them is that you can access other model-factory fields in LazyAttribute
.它们之间的区别在于您可以访问
LazyAttribute
中的其他模型工厂字段。
Here is an example:这是一个例子:
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.User
django_get_or_create = ('email',)
@staticmethod
def gen_email(x):
return x.first_name + "." + x.last_name + "@gmail.com"
first_name = factory.LazyFunction(fake.first_name)
last_name = factory.LazyFunction(fake.last_name)
email = factory.LazyAttribute(gen_email)
password = make_password("ojasojas")
username = factory.LazyAttribute(lambda x: x.first_name + "_" + x.last_name)
You can use lambda
expressions as I've used here for demonstration in making the username
field 'lazy-evaluated', or create functions (static method) and pass them to LazyFunction
/ LazyAttribute
.您可以使用
lambda
表达式,正如我在此处用于使用username
字段“延迟评估”的演示,或创建函数(静态方法)并将它们传递给LazyFunction
/ LazyAttribute
。
You can read more about these classes in official documentation of Factory Boy:您可以在 Factory Boy 的官方文档中阅读有关这些类的更多信息:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.