This comes from Python's parsing rules.

Why?

When you write this:

class UserFactory(factory.django.DjangoModelFactory):
    ⋮
    traffic_source = random.choice(['XYZ', 'ABC', '123', '456'])

Python will execute the following steps:

  1. Read the class declaration body;

  2. Reach the line traffic_source = random.choice(['XYZ', 'ABC', '123', '456']);

  3. Evaluate the call to random.choice, which might return 'ABC';

  4. Once each line of the class body has been read (and its function calls evaluated), create the class:

    UserFactory = type(
        name='UserFactory',
        bases=[factory.django.DjangoModelFactory],
        {'traffic_source': 'ABC', … },
     )
    

As you can see, the call to random.choice is performed only once, when parsing the class declaration.

This is, basically, the reason for all the factory.XXX declarations: they yield an object that will only execute its specific rules when building an instance from the factory.

So, what should you do?

Here, you should use:

  • Either factory.Faker using Faker's random_element provider;
  • Or factory.fuzzy.FuzzyChoice:
class UserFactory(factory.django.DjangoModelFactory):
    ⋮
    traffic_source = factory.Faker('random_element', elements=['XYZ', 'ABC', '123', '456'])
    alt_traffic_source = factory.fuzzy.FuzzyChoice(['XYZ', 'ABC', '123', '456'])

The main difference between factory.Faker('random_choices') and factory.fuzzy.FuzzyChoices is that factory.fuzzy.FuzzyChoices supports lazily evaluating generators; this is useful if you want to choose from a queryset:

  • factory.Faker('random_element', elements=Company.objects.all()) will perform a DB query at import time;
  • factory.fuzzy.FuzzyChoice(Company.objects.all()) will only query the DB the first time UserFactory.create() is called.
Answer from Xelnor on Stack Overflow
🌐
Faker
faker.readthedocs.io › en › master › providers › baseprovider.html
faker.providers. - BaseProvider - Faker's documentation!
>>> Faker.seed(0) >>> for _ in range(5): ... fake.random_choices(elements=('a', 'b', 'c', 'd')) ... ['d', 'b', 'b', 'c'] ['d', 'd', 'd', 'b'] ['c', 'b'] ['c'] ['b', 'c'] >>> Faker.seed(0) >>> for _ in range(5): ... fake.random_choices(elements=('a', 'b', 'c', 'd'), length=10) ...
🌐
Faker
faker.readthedocs.io › en › master › fakerclass.html
Using the Faker Class — Faker 40.13.0 documentation
If no generator supports the provider ... the provider method, return the only generator. If there is more than one applicable generator, and no weights were provided, randomly select a generator using a uniform distribution, i.e. random.choice....
Top answer
1 of 2
20

This comes from Python's parsing rules.

Why?

When you write this:

class UserFactory(factory.django.DjangoModelFactory):
    ⋮
    traffic_source = random.choice(['XYZ', 'ABC', '123', '456'])

Python will execute the following steps:

  1. Read the class declaration body;

  2. Reach the line traffic_source = random.choice(['XYZ', 'ABC', '123', '456']);

  3. Evaluate the call to random.choice, which might return 'ABC';

  4. Once each line of the class body has been read (and its function calls evaluated), create the class:

    UserFactory = type(
        name='UserFactory',
        bases=[factory.django.DjangoModelFactory],
        {'traffic_source': 'ABC', … },
     )
    

As you can see, the call to random.choice is performed only once, when parsing the class declaration.

This is, basically, the reason for all the factory.XXX declarations: they yield an object that will only execute its specific rules when building an instance from the factory.

So, what should you do?

Here, you should use:

  • Either factory.Faker using Faker's random_element provider;
  • Or factory.fuzzy.FuzzyChoice:
class UserFactory(factory.django.DjangoModelFactory):
    ⋮
    traffic_source = factory.Faker('random_element', elements=['XYZ', 'ABC', '123', '456'])
    alt_traffic_source = factory.fuzzy.FuzzyChoice(['XYZ', 'ABC', '123', '456'])

The main difference between factory.Faker('random_choices') and factory.fuzzy.FuzzyChoices is that factory.fuzzy.FuzzyChoices supports lazily evaluating generators; this is useful if you want to choose from a queryset:

  • factory.Faker('random_element', elements=Company.objects.all()) will perform a DB query at import time;
  • factory.fuzzy.FuzzyChoice(Company.objects.all()) will only query the DB the first time UserFactory.create() is called.
2 of 2
1

While not truly random, the effect you're looking for when choosing from among a set of pre-existing records can also be achieved by using FactoryBoy's Iterator, which can also work with a QuerySet. For example, here I wanted every object to be created by someone different from the set of existing fake users:

from django.contrib.auth import get_user_model
...

# Then, within a factory class, for one of the fields:
created_by = factory.Iterator(get_user_model().objects.all())
🌐
Fakerjs
v6.fakerjs.dev › api › random
Random | Faker
Generates random values of different kinds. Some methods are deprecated and have been moved to dedicated modules. ... Generating a string consisting of lower/upper alpha characters based on count and upcase options. ... faker.random.alpha(options: number | { bannedChars: readonly string[], ...
🌐
FakerJS
fakerjs.dev › api › helpers.html
Helpers | Faker
Module with various helper methods providing basic (seed-dependent) operations useful for implementing faker methods. A particularly helpful method is arrayElement() which returns a random element from an array.
🌐
Blue Book
lyz-code.github.io › blue-book › coding › python › faker
Faker - The Blue Book
import random from faker import Faker from faker.providers import BaseProvider fake = Faker() # Our custom provider inherits from the BaseProvider class TravelProvider(BaseProvider): def destination(self): destinations = ['NY', 'CO', 'CA', 'TX', 'RI'] # We select a random destination from the list and return it return random.choice(destinations) # Add the TravelProvider to our faker object fake.add_provider(TravelProvider) # We can now use the destination method: print(fake.destination()) If you want to give arguments when calling the provider, add them to the provider method.
Find elsewhere
🌐
Tabnine
tabnine.com › home page › code › java › com.github.javafaker.faker
Java Examples & Tutorials of Faker.random (com.github.javafaker) | Tabnine
* * @param options The varargs to take a random element from. * @param <E> The type of the elements in the varargs. * @return A randomly selected element from the varargs. */ public <E> E option(E... options) { return options[faker.random().nextInt(options.length)]; } origin: DiUS/java-faker ·
🌐
GitHub
github.com › stympy › faker › issues › 1113
Selecting a single item from user-supplied data at random. · Issue #1113 · faker-ruby/faker
January 11, 2018 - Wondering if anyone else would find value in having a way to select a random element from a user-supplied set of data? For example: Faker::Random.array(['Approved', 'Pending', 'Denied']) #=> Pending I use this a lot when I'm writing test...
Author   jaredmeakin
🌐
GitHub
github.com › faker-js › faker › issues › 3222
Add method/option to pick elements from an array multiple times · Issue #3222 · faker-js/faker
October 26, 2024 - function multipleArrayElements(values: T[], count: numberOrRange) { const valuesLength = values.length: const divisions = Math.floor(Math.log(Number.MAX_SAFE_INTEGER) / Math.log(valuesLength)); const base = valuesLength ** divisions; const repeats = Math.floor(count / divisions); const remains = count % divisions const result = []; for(let i = 0; i<repeats; i++) { let random = faker.number.int(base); for (let j=0; j<divisions; j++) { const index = random % valuesLength; random /= valuesLength; result.push(values[index]); } } let random = faker.number.int(base); for (let j=0; j<remains; j++) { const index = random % valuesLength; random /= valuesLength; result.push(values[index]); } return result; }
Author   ST-DDT
🌐
Netlify
fakerjsdocs.netlify.app › api › random.html
random | Un-Official Docs
Takes an array and returns a random element of the array ... faker.random.objectElement(); // car faker.random.objectElement({ name:'bob', color: 'blue', age: 22}); // bob faker.random.objectElement({ name:'bob', color: 'blue', age: 22}, 'key'); // name
🌐
Datafaker
datafaker.net › documentation › usage
Basic usage - Datafaker
The following example assumes you want to retrieve a random value from the Day enum. ... enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } private final Options opt = faker.options(); opt.option(Day.class); Back to top
🌐
GitHub
github.com › joke2k › faker › issues › 1183
Please support weighted choices · Issue #1183 · joke2k/faker
May 18, 2020 - Since Python 3.6, random.choices has supported passing in weights for the choices, which would allow for more realistic generation of data sets like random languages (#1179). It would be nice of fa...
Published   May 18, 2020
Author   ex-nerd
🌐
FakerPHP
fakerphp.org › formatters › numbers-and-strings
Numbers and Strings - FakerPHP / Faker
Generates a random integer, containing between 0 and $nbDigits amount of digits. When the $strict parameter is true, it will only return integers with $nbDigits amount of digits. echo $faker->randomNumber(5, false); // 123, 43, 19238, 5, or ...
🌐
Faker
faker.readthedocs.io › en › master › providers › faker.providers.lorem.html
faker.providers.lorem — Faker 40.11.1 documentation
Suddenly seek choice produce.', 'Of door research tell. When clearly type up. Wait education think similar particular before.\nAction economy several hit simple personal home.\nLet stop camera report foreign agency list miss.'] >>> Faker.seed(0) >>> for _ in range(5): ...
🌐
Faker
faker.readthedocs.io
Welcome to Faker’s documentation! — Faker 40.13.0 documentation
When using Faker for unit testing, you will often want to generate the same data set. For convenience, the generator also provides a seed() method, which seeds the shared random number generator.
🌐
SAP Community
community.sap.com › t5 › technology-blog-posts-by-sap › generate-custom-datasets-using-python-faker › ba-p › 13511383
Generate custom datasets using Python Faker - SAP Community
February 25, 2023 - Note: To create categorical columns based on a choice, you can also use faker's random_element method as an option to numpy's random.choice when you don't need to specify weights. Your choice! In the example below, I used both for industry and industry2.