Created
March 4, 2020 22:02
-
-
Save mahenzon/30714f84135069b8a7dee3a4d7728210 to your computer and use it in GitHub Desktop.
Demo creating fixtures for Django using mixer and Factory Boy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# myapp/models.py | |
from django.db import models | |
class MyModel(models.Model): | |
class Meta: | |
abstract = True | |
def __str__(self): | |
data = [f'{k}={v!r}' for k, v in self.__dict__.items() if not k.startswith('_')] | |
return f'{self.__class__.__name__}({", ".join(data)})' | |
class Group(MyModel): | |
name = models.CharField(max_length=50) | |
class User(MyModel): | |
lang = models.CharField(max_length=2) | |
username = models.CharField(max_length=20) | |
# created_at = models.DateTimeField(auto_now_add=True) | |
# updated_at = models.DateTimeField(auto_now=True) | |
group = models.ForeignKey(Group, on_delete=models.PROTECT) | |
birth_dt = models.DateTimeField() | |
birth_month = models.IntegerField() | |
class Employee(User): | |
internal_id = models.IntegerField() | |
internal_email = models.EmailField() | |
class Order(MyModel): | |
STATES = ( | |
('Pending', 'pending'), | |
('Awaiting shipment', 'awaiting_shipment'), | |
('Shipped', 'shipped'), | |
('Delivered', 'delivered'), | |
) | |
state = models.CharField(max_length=30, choices=STATES) | |
shipped_on = models.DateTimeField(null=True) | |
shipped_by = models.ForeignKey(Employee, on_delete=models.PROTECT, null=True) | |
delivered_by = models.DateTimeField(null=True) | |
# myapp/management/commands/fixtures_mixer.py | |
""" | |
https://mixer.readthedocs.io/en/latest/api.html | |
""" | |
from faker import Faker | |
from mixer.backend.django import mixer | |
from django.core.management import BaseCommand | |
from factoriesdemo.models import User, Group | |
fake = Faker() | |
def create_all(): | |
""" | |
:return: | |
""" | |
user = mixer.blend(User) | |
print(user) | |
user = mixer.blend(User, lang='en') | |
print(user) | |
user = mixer.blend(User, group__name='grp_name') | |
print(user, user.group) | |
user = mixer.blend(User, username=fake.user_name) | |
print(user) | |
users = mixer.cycle(3).blend(User) | |
print(users) | |
group = mixer.blend(Group) | |
print(group) | |
groups = mixer.cycle(3).blend(Group) | |
print(groups) | |
users = mixer.cycle(3).blend( | |
User, | |
username=(n for n in ('james', 'ben', 'john')), | |
# group=mixer.SELECT, | |
) | |
print(users) | |
users = mixer.cycle(2).blend( | |
User, | |
username=mixer.sequence('john', 'mike') | |
) | |
print(users) | |
users = mixer.cycle(2).blend(User, username=mixer.sequence(lambda c: f"uname{c}")) | |
print(users) | |
user = mixer.blend(User, username=mixer.MIX.lang) | |
print(user) | |
class Command(BaseCommand): | |
help = 'Using mixer' | |
def handle(self, *args, **options): | |
create_all() | |
""" | |
User(id=196, lang='xV', username='johnhanson', group_id=241, birth_dt=datetime.datetime(1981, 4, 3, 8, 47, 37), birth_month=8506) | |
User(id=197, lang='en', username='philip16', group_id=242, birth_dt=datetime.datetime(1997, 12, 6, 11, 21, 56), birth_month=6897) | |
User(id=198, lang='pu', username='josephmcguire', group_id=243, birth_dt=datetime.datetime(1987, 3, 31, 16, 57, 38), birth_month=967) Group(id=243, name='grp_name') | |
User(id=199, lang='xQ', username='nbaker', group_id=244, birth_dt=datetime.datetime(1989, 12, 25, 3, 48, 22), birth_month=7415) | |
[<User: User(id=200, lang='aO', username='deananthony', group_id=245, birth_dt=datetime.datetime(1992, 8, 18, 14, 46, 4), birth_month=2001)>, <User: User(id=201, lang='qP', username='markbass', group_id=246, birth_dt=datetime.datetime(1993, 3, 22, 5, 46, 38), birth_month=9800)>, <User: User(id=202, lang='AG', username='dawnhull', group_id=247, birth_dt=datetime.datetime(1999, 12, 9, 11, 31, 59), birth_month=9317)>] | |
Group(id=248, name='Brianna Torres') | |
[<Group: Group(id=249, name='Tara Hill')>, <Group: Group(id=250, name='David Murray')>, <Group: Group(id=251, name='Billy Hall')>] | |
[<User: User(id=203, lang='pz', username='james', group_id=252, birth_dt=datetime.datetime(1976, 12, 26, 12, 29, 34), birth_month=7937)>, <User: User(id=204, lang='cR', username='ben', group_id=253, birth_dt=datetime.datetime(2010, 11, 8, 12, 10, 12), birth_month=2952)>, <User: User(id=205, lang='fM', username='john', group_id=254, birth_dt=datetime.datetime(2014, 2, 14, 6, 53, 55), birth_month=951)>] | |
[<User: User(id=206, lang='Oa', username='john', group_id=255, birth_dt=datetime.datetime(1971, 8, 29, 6, 18, 45), birth_month=1883)>, <User: User(id=207, lang='TF', username='mike', group_id=256, birth_dt=datetime.datetime(2005, 1, 4, 16, 59, 46), birth_month=1215)>] | |
[<User: User(id=208, lang='TE', username='uname0', group_id=257, birth_dt=datetime.datetime(1988, 6, 13, 0, 38, 22), birth_month=8540)>, <User: User(id=209, lang='Xk', username='uname1', group_id=258, birth_dt=datetime.datetime(2000, 5, 11, 18, 39, 10), birth_month=3621)>] | |
User(id=210, lang='Jq', username='Jq', group_id=259, birth_dt=datetime.datetime(2002, 9, 2, 5, 42, 35), birth_month=8243) | |
""" | |
# myapp/management/commands/fixtures_fb.py | |
import factory | |
from faker import Faker | |
from django.core.management import BaseCommand | |
from factoriesdemo.models import User, Order, Group, Employee | |
fake = Faker() | |
class GroupFactory(factory.django.DjangoModelFactory): | |
class Meta: | |
model = Group | |
name = factory.Faker('word') | |
class UserFactory(factory.django.DjangoModelFactory): | |
class Meta: | |
model = User | |
lang = factory.Iterator(['en', 'fr', 'es', 'it', 'de']) | |
username = factory.Sequence(lambda n: "user%03d" % n) | |
group = factory.SubFactory(GroupFactory) | |
birth_dt = factory.Faker('date_of_birth') | |
birth_month = factory.SelfAttribute('birth_dt.month') | |
class EmployeeFactory(UserFactory): | |
class Meta: | |
model = Employee | |
internal_id = factory.Sequence(int) | |
internal_email = factory.LazyAttribute(lambda o: '%s.%s@%s' % (o.username, o.internal_id, fake.domain_name())) | |
class OrderFactory(factory.django.DjangoModelFactory): | |
class Meta: | |
model = Order | |
state = factory.Iterator(Order.STATES[:2], getter=lambda c: c[1]) | |
shipped_on = None | |
shipped_by = None | |
delivered_by = None | |
class Params: | |
shipped = factory.Trait( | |
state='shipped', | |
shipped_on=factory.Faker('date_between', start_date='-30m', end_date='today'), | |
shipped_by=factory.SubFactory(EmployeeFactory), | |
) | |
delivered = factory.Trait( | |
state='delivered', | |
shipped_on=factory.Faker('date_between', start_date='-10m', end_date='-5m'), | |
shipped_by=factory.SubFactory(EmployeeFactory), | |
delivered_by=factory.Faker('date_between', start_date='-30d', end_date='-5d'), | |
) | |
def create_all(): | |
""" | |
:return: | |
""" | |
group = GroupFactory() | |
print(group) | |
user = UserFactory() | |
print(user) | |
employee = EmployeeFactory() | |
print(employee) | |
order = OrderFactory() | |
print(order) | |
order = OrderFactory() | |
print(order) | |
orders = OrderFactory.build_batch(3) | |
print(orders) | |
order = OrderFactory.create(shipped=True) | |
print(order, order.shipped_by) | |
order = OrderFactory.build(shipped=True) | |
print(order, order.shipped_by) | |
order = OrderFactory(delivered=True) | |
print(order, order.shipped_by) | |
class Command(BaseCommand): | |
help = 'Using Factory Boy' | |
def handle(self, *args, **options): | |
create_all() | |
""" | |
Group(id=260, name='watch') | |
User(id=211, lang='en', username='user000', group_id=261, birth_dt=datetime.date(1904, 10, 29), birth_month=10) | |
Employee(id=212, lang='fr', username='user001', group_id=262, birth_dt=datetime.date(1992, 8, 7), birth_month=8, user_ptr_id=212, internal_id=1, internal_email='[email protected]') | |
Order(id=21, state='pending', shipped_on=None, shipped_by_id=None, delivered_by=None) | |
Order(id=22, state='awaiting_shipment', shipped_on=None, shipped_by_id=None, delivered_by=None) | |
[<Order: Order(id=None, state='pending', shipped_on=None, shipped_by_id=None, delivered_by=None)>, <Order: Order(id=None, state='awaiting_shipment', shipped_on=None, shipped_by_id=None, delivered_by=None)>, <Order: Order(id=None, state='pending', shipped_on=None, shipped_by_id=None, delivered_by=None)>] | |
Order(id=23, state='shipped', shipped_on=datetime.date(2020, 3, 3), shipped_by_id=213, delivered_by=None) Employee(id=213, lang='es', username='user002', group_id=263, birth_dt=datetime.date(1941, 3, 19), birth_month=3, user_ptr_id=213, internal_id=2, internal_email='[email protected]') | |
Order(id=None, state='shipped', shipped_on=datetime.date(2020, 3, 3), shipped_by_id=None, delivered_by=None) Employee(id=None, lang='it', username='user003', group_id=None, birth_dt=datetime.date(1910, 12, 23), birth_month=12, user_ptr_id=None, internal_id=3, internal_email='[email protected]') | |
Order(id=24, state='delivered', shipped_on=datetime.date(2020, 3, 3), shipped_by_id=214, delivered_by=datetime.date(2020, 2, 5)) Employee(id=214, lang='de', username='user004', group_id=264, birth_dt=datetime.date(1927, 1, 12), birth_month=1, user_ptr_id=214, internal_id=4, internal_email='[email protected]') | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment