Comments (3)
I'm so glad that you got to this within 3 years, I was worried we'd go into the 4th year..... 😆
I understand your thinking and I think I do care about existing values in the database sometimes. So a ban list does not sound like a bad idea.
from factory_djoy.
Had some time to think about this 😂
This week I've wished for a unique generator for strings when working with Factory Boy. I'm not satisfied with using Sequences to guarantee unique values - especially for stringy values which are not meant to contain numbers.
I've started work on uFaker to add functionality to Faker to make it easier to generate unique values and or exclude undesired ones.
Quick recap: factory_djoy
does two things when generating user names for Django Users:
-
Generates a unique
username
usingunique_username()
(https://github.com/jamescooke/factory_djoy/blob/master/factory_djoy/factories.py#L108). Using uFaker would mean that this could be reduced to justufake.user_name()
because uFaker will guarantee uniqueness. -
Checks against the existing usernames in the database. If the generated username is already in the db, then a new one is generated.
So, back to the original question:
Would it be possible to provide the Username generator as it's own standalone module/provider?
Do you care about values in the database already?
If no - then would ufake.user_name()
work? My plan is to wire a ufake
instance into factory_djoy
so that unique values can be easily generated across multiple calls to factories.
If yes - then UniqueUsername()
could be made available. My main concern would be that this would not be generic enough to be helpful - for example if the model field name or database column name change.
What I'm thinking of for the "yes I care about existing values in the database" situation is a recipe that uses a ban list:
from factory_djoy import CleanModelFactory, ufake
from project.accounts import Account
class AccountFactory(CleanModelFactory):
class Meta:
model = Account
@lazy_attribute
def username(self):
all_usernames = Account.objects.values_list('username', flat=True)
return ufake.user_name(ban=all_usernames)
What do you think? Would the recipe be powerful enough for what you're looking for?
Either way, my plan is to build out uFaker to the API in its README and then replace the username generation in this library with the recipe above.
from factory_djoy.
Just a note to self with an example for testing.
Given a Game
model that keeps a single unique value pointing a Server FK on another system:
class Game(models.Model):
server_id = models.IntegerField(unique=True)
code = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now=True)
Then we would have a factory (note the change of import name from the Username
example above - this is so that the API matches Factory Boy):
from factory import Faker
from factory_djoy import CleanModelFactory, uFaker
from games.models import Game
class GameFactory(CleanModelFactory):
class Meta:
model = Game
server_id = uFaker('pyint') # This guarantees unique values for this ID
code = Faker('word') # We don't care about uniqueness here.
This would then mean that a large number of valid Game
instances can be created without the server_id
accidentally colliding and without using Factory Boy's sequence
solution: GameFactory.create_batch(999)
.
It also means that we can easily test what happens when there are missing values without the chance of collision, but maintaining some randomness:
def test_missing():
"""
When no games can be found, serializer is valid, but `_game` is `None`.
"""
GameFactory.create_batch(3, server_id__ban=[29])
serializer = GameSearchSerializer(data={'server_id': 29})
result = serializer.is_valid()
assert result is True, serializer.errors
assert serializer._game is None
from factory_djoy.
Related Issues (20)
- Migrate build system off Travis, use GHA
- Add explicit support for Python>=3.9
- Drop support for Python 3.6
- Remove compiled requirements for Django versions, trust tox to install good versions HOT 1
- Adjust Django support, add Django 4 HOT 1
- Fix RTD build: failing because of config issue
- Make RTD default version v1
- Version difference in docs
- Test on Django 1.11
- Improve testing
- Test on Python 3.7
- Bump dependency on Factory Boy to >= 2.11
- Add better stack trace when validation fails HOT 1
- Automate package updates
- Add getting started info to README
- Test on Python 3.8
- Support Django 3
- Add support for Django 3.1
- Remove support for py35
- Remove support for Django 1.11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from factory_djoy.