Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/adgaudio/fixturefactory
Automate Django fixture creation. Easier than Factoryboy and Factorygirl!
https://github.com/adgaudio/fixturefactory
Last synced: 15 days ago
JSON representation
Automate Django fixture creation. Easier than Factoryboy and Factorygirl!
- Host: GitHub
- URL: https://github.com/adgaudio/fixturefactory
- Owner: adgaudio
- Created: 2011-10-13T15:09:18.000Z (about 13 years ago)
- Default Branch: master
- Last Pushed: 2011-11-30T16:37:57.000Z (almost 13 years ago)
- Last Synced: 2024-10-03T11:12:04.145Z (about 1 month ago)
- Language: Python
- Homepage:
- Size: 126 KB
- Stars: 7
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README
Awesome Lists containing this project
README
About:
===fixturefactory is a great library for creating Django fixtures.
Within fixturefactory.py, you will find a BaseFactory and DjangoMixin.
* The BaseFactory class was written to make developing with factories for other purposes or frameworks very simple.
* The DjangoMixin class provides some methods to make fixture creation easy.Please fork, give feedback, or add an issue to the tracker!
Use Cases:
===Creating instances of a model
>>> ChildFactory()
>>> ChildFactory(save_to_db=False)Create and retrieve an instance
>>> child1 = ChildFactory().last_obj_created
>>> child2 = ChildFactory()() # same as aboveDynamically passing params to your factories to override factory defaults
>>> BrotherFactory(pk1=child1.pk, pk2=1) # (params become available as class vars)
Defining your Factories:
===All factories you create have these basic characteristics:
* Must inherit from BaseFactory (should also inherit from DjangoMixin to simplify working with Django)
* Must have a class variable, 'model', which accepts parameters and has a save() method
* Must have a method, 'getparams', which returns a dict containing the params necessary to instantiate the model
* Optionally, can have a method, 'lastly', which can be executed after model instantiation (useful for m2m)The basic template looks like this:
class ChildFactory(BaseFactory, DjangoMixin):
model = myapp.models.SomeModeldef getparams(self):
return {}#optional method
def lastly(self):
passExample Implementations:
---The following factory generates generic Django users. A more advanced implementation may make use of randomly generated text, etc. Note that in this example, getparams returns locals(), which is a dict of the local environment. If you have defined temporary variables in the getparams() method, this approach can cause django to raise an exception, but it also brings up the point that getparams() should not do anything complicated or temporary. The purpose of getparams() is to define parameters that will eventually be used to instantiate the factory's model
class UserFactory(BaseFactory, DjangoMixin):
model = django.contrib.auth.models.Userdef getparams(self):
pk = self.getUnusedPk() # Utilize the methods in DjangoMixin
username = 'markov_%s' % pk
password = 'sha1$86d38$73c3ea4bbe34f27d06b53115a8af1cd66ff263b3' # using lastly(), you can avoid encryption stuff
return locals()#def lastly(self): pass # optional
Lets say you'd rather let django handle password encryption. The lastly() method will execute code after the object has been created. An interesting point here is that all variables defined in getparams() become available to lastly() as class variables
def lastly(self):
a = self.last_obj_created
a.set_password(self.username) # sets the password by default the defined usernameAlso, you can choose not to execute lastly at time of instantiation:
>>> UserProfileFactory(lastly=False)
UserProfileFactory: last_obj_createdThis next example shows how to implement Foreign Keys, where the UserProfile has a Foreign Key on the above example's User model. Note that the 'user' variable in getparams() is an instance of the UserFactory's model
class UserProfileFactory(BaseFactory, DjangoMixin):
model = myapp.models.UserProfiledef getparams(self):
"""An example of a foreign key"""
user = UserFactory().last_obj_created
pk = user.pk #this User and UserProfile share the same primary key
return locals()Implementing Many to Many Relationships are also very easy, and there are a couple different ways to do this. This example utilizes fixturefactory's 'lastly' method to execute some code after the model has been instantiated. In this case, a many to many connection is made using the instantiated model.
For this example, lets assume the UserProfile model has a many to many relationship with a model called 'Group'
class UserProfileFactory(BaseFactory, DjangoMixin):
model = myapp.models.UserProfiledef getparams(self):
return {} # lets assume you have already coded this partdef lastly(self):
"""Creating a many to many relationship after model instantiation"""
inst = self.last_obj_created
inst.groups.add(Group.objects.get(pk=1))Here's another many to many example. If you didn't want to define a method, you can add m2m relationship after instantiation
>>> userprofile_instance = UserProfileFactory(lastly=False)()
>>> group = Group.objects.get(pk=1)
>>> userprofile_instance.groups.add(group)If you wanted to require a parameter at runtime, your factory might look like this:
class RelatedUserFactory(BaseFactory, DjangoMixin):
model = myapp.models.RelatedUserdef getparams(self):
pk1 = self.pk1 #NOTE the class var (self.pk1) and local var (pk1) must have the same name
pk2 = self.pk2
return locals()>>> RelatedUserFactory(pk1=3, pk2=5) #keywords 'pk1' and 'pk2' required in this case.
Development:
===To use BaseFactory for a purpose other than Django fixtures, you'd have to (probably) override the BaseFactory.create() method. You will also probably want to create a mixin to simplify development (see DjangoMixin for an example).
Any parameters passed in to the Factory at time of instantiation are available as class variables. This is useful for mixin development,when you may need to know what parameters are overriding defaults defined by getparams().
I hope all this encourages you to use fixturefactory!