Factory_boy не создает разные объекты пользователя Django

Я новичок в Factory_boy с Django. Потратив некоторое время, я понял, как создать фабрику для модели пользователя.

Я использую пользовательскую модель по умолчанию, и следующая моя фабрика. Я использую 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

Теперь в оболочке джанго

Я использую UserFactory.create() для создания пользователя. это работает нормально. Можно ли зациклиться на инструкции create и создать 5 разных пользователей? Теперь, когда я это делаю, я получаю только одного пользователя (созданный один раз и «получить» 4 раза) следующим образом. Что мне не хватает?введите здесь описание изображения


person Ojas Kale    schedule 10.03.2017    source источник
comment
и если я удалю оператор django_get_or_create = ('email',), запуск оператора crate дважды вызовет ошибку уникального ограничения   -  person Ojas Kale    schedule 10.03.2017
comment
Я попробовал ваш пример кода без Faker, заменив строку имени пользователя на: username = factory.Sequence(lambda n: 'user' + n,str). Faker, но я думаю, вам следует посмотреть, как он используется для решения этого вопроса.   -  person Dashdrum    schedule 11.03.2017


Ответы (2)


Вы определяете атрибуты класса для своей фабрики, которые оцениваются только тогда, когда класс определен. email = first_name+"."+last_name+"@gmail.com" будет оцениваться один раз, а не каждый раз, когда вы вызываете UserFactory.create(), отсюда и уникальные ошибки ограничения. Обычным решением для этого является определение атрибутов экземпляра через __init__(), но у FactoryBoy есть свое собственное решение: ленивые атрибуты.

person mindcruzer    schedule 10.03.2017
comment
Что ж, это решает проблему уникальных ограничений. но все же я не могу создавать разные объекты с помощью цикла. Спасибо. - person Ojas Kale; 10.03.2017
comment
вы пробовали что-то вроде for user in UserFactory.build_batch(10): user.save()? - person mindcruzer; 10.03.2017
comment
Я тоже так пробовал, но не работает @mindcruzer - person Ojas Kale; 10.03.2017
comment
Это был не просто ответ на проблему уникальности при использовании подделки, но и отличное напоминание о том, как ведут себя атрибуты класса. +1 - person ThatsAMorais; 14.12.2017

Это может быть не лучшее решение, но это обходной путь, который я использовал в последнее время. Я установил следующие глобальные:

NAMES = [factory.Faker('name')._get_faker().name() for i in range(5)]

В этом случае приведенное выше сгенерирует список из 5 поддельных имен.

ПРИМЕЧАНИЕ: это не гарантирует уникальность имени (поскольку FuzzyChoice просто выберет одно из списка).

и на вашем заводе:

name = factory.LazyAttribute(lambda obj: factory.fuzzy.FuzzyChoice(NAMES).fuzz()) 
person too_many_questions    schedule 20.04.2017