Django create fake test data with custom command

◾️ install django-seed for fake test data

$ pipenv install django_seed

  • configure settings.py
# https://pypi.org/project/django-seed/
THIRD_PARTY_APPS = ["django_countries", "django_seed"]

◾️ custom command

faker usage

  • create user with is_staff=False and is_superuser=False

seeder.add_entity(User, number, {“is_staff”: False, “is_superuser”: False})

from django.core.management.base import BaseCommand
from django_seed import Seed
from users.models import User


# https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/
class Command(BaseCommand):

    help = "This command creates many users"

    def add_arguments(self, parser):
        parser.add_argument(
            "--number", default=1, type=int, help="How many users do you want to create"
        )

    def handle(self, *args, **options):
        number = options.get("number")
        seeder = Seed.seeder()
        seeder.add_entity(User, number, {"is_staff": False, "is_superuser": False})
        seeder.execute()
        self.stdout.write(self.style.SUCCESS(f"{number} Users created!"))
  • current user info of admin panel
  • Run custom command for creating fake users
$ python manage.py seed_users --number 3
3 Users created!

  • created user

◾️If models have foreign key/many to many field, how to add entity?

  • room model
class Room(core_models.AbstractTimeStampModel):
    """ Room Model Definition """

    name = models.CharField(max_length=140)
    description = models.TextField()
    country = CountryField()
    city = models.CharField(max_length=80)
    price = models.IntegerField()
    address = models.CharField(max_length=140)
    guests = models.IntegerField()
    beds = models.IntegerField()
    bedrooms = models.IntegerField()
    baths = models.IntegerField()
    check_in = models.TimeField()
    check_out = models.TimeField()
    instant_book = models.BooleanField(default=False)
    host = models.ForeignKey(
        "users.User", related_name="rooms", on_delete=models.CASCADE
    )
    room_type = models.ForeignKey(
        "RoomType", related_name="rooms", on_delete=models.SET_NULL, null=True
    )
    amenities = models.ManyToManyField("Amenity", related_name="rooms", blank=True)
    facilities = models.ManyToManyField("Facility", related_name="rooms", blank=True)
    house_rules = models.ManyToManyField("HouseRule", related_name="rooms", blank=True)
import random
from django.core.management.base import BaseCommand
from django.contrib.admin.utils import flatten
from django_seed import Seed
from users import models as user_models
from rooms import models as room_models


# https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/
class Command(BaseCommand):

    help = "This command creates many rooms"

    def add_arguments(self, parser):
        parser.add_argument(
            "--number", default=1, type=int, help="How many rooms do you want to create"
        )

    def handle(self, *args, **options):
        number = options.get("number")
        seeder = Seed.seeder()

        # We have to select Foreignkey range with user and roomType
        all_users = user_models.User.objects.all()
        room_types = room_models.RoomType.objects.all()
        seeder.add_entity(
            room_models.Room,
            number,
            {
                "name": lambda x: seeder.faker.address(),
                "host": lambda x: random.choice(all_users),
                "room_type": lambda x: random.choice(room_types),
                "guests": lambda x: random.randint(1, 20),
                "price": lambda x: random.randint(1, 300),
                "beds": lambda x: random.randint(1, 5),
                "bedrooms": lambda x: random.randint(1, 5),
                "baths": lambda x: random.randint(1, 5),
            },
        )

        created_rooms = seeder.execute()
        # create ammenities/facilities/photos of each room
        # print(list(created_rooms.values()))
        created_rooms_pk_list = flatten(list(created_rooms.values()))
        amenities = room_models.Amenity.objects.all()
        facilities = room_models.Facility.objects.all()
        rules = room_models.HouseRule.objects.all()
        for room_pk in created_rooms_pk_list:
            room = room_models.Room.objects.get(pk=room_pk)
            # create photo
            for i in range(3, random.randint(10, 13)):
                room_models.Photo.objects.create(
                    caption=seeder.faker.sentence(),
                    room=room,
                    file=f"room_photos/{random.randint(1,31)}.webp",
                )

            # create ammenities
            for a in amenities:
                magic_number = random.randint(0, 15)
                if magic_number % 2 == 0:
                    room.amenities.add(a)
            # create facilities
            for f in facilities:
                magic_number = random.randint(0, 15)
                if magic_number % 2 == 0:
                    room.facilities.add(f)
            # create house rules
            for r in rules:
                magic_number = random.randint(0, 15)
                if magic_number % 2 == 0:
                    room.house_rules.add(r)
        self.stdout.write(self.style.SUCCESS(f"{number} Rooms created!"))
  • check
◾️type=int for integer parsing
parser.add_argument(
            "--number", default=1, type=int, help="How many rooms do you want to create"
        )
◾️we can use hard coded kind like this
"preference": lambda x: random.choice([User.PREF_BOOKS, User.PREF_MOVIES]),

◾️seeder.faker for name or year
"name": lambda x: seeder.faker.name(),
"year": lambda x: seeder.faker.year(),

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です