Permalink
Browse files

added hook function, update in readme and facebook

  • Loading branch information...
1 parent 829ac1e commit 2e6ff9d70484f8e8fcf3ce83fd318d8fe1c651b5 @sbaechler committed Mar 13, 2012
View
@@ -7,43 +7,40 @@ Django-Scaffolding creates placeholder data for your app.
Usage
=====
-Create a Scaffolding class within your model which contains the callbacks to
-fill it with the necesarry data.
+Create a ``scaffolds.py`` module within your app directory which contains the Scaffolding classes.
Sample ``models.py``::
- class MyModel(models.Model):
+ class Entry(models.Model):
first_name = models.CharField('First Name', max_length=32)
last_name = models.CharField('Last Name', max_length=32)
comment = models.TextField('Comment')
image = models.ImageField(upload_to='uploads/%Y/%m/%d', blank=True, null=True)
contest = models.ForeignKey(Contest)
...
-Sample ``scaffold.py``::
+Sample ``scaffolds.py``::
import scaffolding
- from scaffolding.external.facebook_graph import FacebookTestUser
from scaffolding.library.flickr import FlickrInteresting
from myapp.models import Customer
- class CustomerScaffold(object):
+ class EntryScaffold(object):
first_name = scaffolding.FirstName(max_length=32)
last_name = scaffolding.LastName(max_length=32)
comment = scaffolding.LoremIpsum(paragraphs=1)
- contest = scaffolding.RandInt(min=1, max=2)
+ contest = scaffolding.ForeignKey(queryset=Contest.objects.filter(name='testcontest'))
image = scaffolding.RandomInternetImage(backend=FlickrInteresting)
- scaffolding.register(Customer, CustomerScaffold)
+ scaffolding.register(Entry, EntryScaffold)
-Mind the syntax for ForeignKey fields. You can assign an integer to the field.
-But make sure the element with the corresponding key does exist. Of course you
-can also assign an object to the FK field.
+Mind the syntax for ForeignKey fields. You can assign an integer to the field
+but make sure the element with the corresponding key does exist.
+Of course you can also assign an object to the FK field.
To use the flickr library you need to have the Flickr API: http://stuvel.eu/flickrapi installed.
-
Run the management command to create the data::
manage.py scaffold myapp.MyModel 20
@@ -90,6 +87,13 @@ RandInt
Generates a random integer between min and max.
+ForeignKey
+----------
+
+Takes a queryset and iterates through it. Assigns the
+item as ForeignKeys to the field. Wraps around if there
+are not enough items.
+
RandomInternetImage
-------------------
@@ -117,4 +121,6 @@ FacebookTestUser
Creates a Facebook User from the test users pool of the Facebook app.
If there aren't enough test users new ones are automatically created.
+This requires the django-facebook-graph API.
+https://github.com/feinheit/django-facebook-graph
View
@@ -17,14 +17,6 @@
def generic_autodiscover(module_name):
- """
- I have copy/pasted this code too many times...Dynamically autodiscover a
- particular module_name in a django project's INSTALLED_APPS directories,
- a-la django admin's autodiscover() method.
-
- Usage:
- generic_autodiscover('commands') <-- find all commands.py and load 'em
- """
for app in settings.INSTALLED_APPS:
try:
@@ -51,6 +43,6 @@ def scaffold_for_model(model):
"""
# Load scaffold modules of all INSTALLED_APPS
- generic_autodiscover('scaffold')
+ generic_autodiscover('scaffolds')
return _registry[model]
@@ -4,7 +4,7 @@
from facebook.models import TestUser, User
from facebook.testusers import TestUsers
from facebook.utils import get_app_dict, get_static_graph
-from scaffolding import Tube
+from scaffolding.tubes import Tube
class FacebookTestUser(Tube):
@@ -16,38 +16,40 @@ def __init__(self, app_name=None, unique=False, **kwargs):
self.graph = get_static_graph(self.app_name)
self.testusers = TestUsers(self.graph)
self.users = []
+ self.index = 0
+ def __iter__(self):
+ return self
+
+ def set_up(self, cls, count, **kwargs):
+ testuser_list = self.testusers.get_test_users()
+
+ if count and count > len(testuser_list):
+ remaining = count-len(testuser_list)
+ try:
+ print 'Not enough Test users (%s). Generating %s more.\n' %(len(testuser_list),
+ self.count-len(testuser_list))
+ except IOError:
+ pass
+ for i in range(remaining):
+ self.generate_new_user()
+ self.user_for_testuser(testuser_list)
+
+ def user_for_testuser(self, testuser_list):
try:
print u'Checking for Facebook Test users...:\n'
except IOError:
pass
- testuser_list = self.testusers.get_test_users()
for testuser in testuser_list:
user, created = User.objects.get_or_create(id=int(testuser.id))
if created:
user.get_from_facebook(self.graph, save=True)
self.users.append(user)
-
try:
print u'Done. Found %s testusers.' % len(testuser_list)
except IOError:
pass
- if self.count and self.count > len(testuser_list):
- remaining = self.count-len(testuser_list)
- try:
- print 'Not enough Test users (%s). Generating %s more.\n' %(len(testuser_list),
- self.count-len(testuser_list))
- except IOError:
- pass
- for i in range(remaining):
- self.generate_new_user()
-
- self.index = 0
-
- def __iter__(self):
- return self
-
def generate_new_user(self):
newuser = self.testusers.generate_new_test_user(installed=True, permissions=['email'])
try:
@@ -48,14 +48,10 @@ def make_factory(self, cls, count):
for field_name in field_names:
generator = getattr(scaffold, field_name, None)
if generator:
+ generator.set_up(cls, count)
@matthiask

matthiask Mar 14, 2012

Contributor

Ein solcher Hook macht natürlich Sinn für einige Use Cases. Das einzige was ein bisschen schade ist daran: Als Tubes konnten bisher einfache Generators (Funktionen mit yield Statements) verwendet werden, das geht jetzt, mit dem set_up nicht mehr.

Vorschlag: https://github.com/matthiask/django-scaffolding/commit/31858b3137c00d407da1131a8f38700c8c8c40d4

Aber mal sehen, vielleicht fällt mir dazu noch was Schlaues ein. Das Problem mit den Abhängigkeiten unter Feldern ist ja auch noch nicht gelöst.

fields[field_name] = generator
text.append(u'%s: %s; ' % (field_name, fields[field_name]))
-# if hasattr(cls.Scaffolding, '%s_id' % field_name):
-# generator, kwargs = getattr(cls.Scaffolding, '%s_id' % field_name)
-# fields['%s_id' % field_name] = generator(count=count, cls=cls, **kwargs)
-# text += u'%s_id: %s; ' % (field_name, fields['%s_id' % field_name])
-
self.stdout.write(u'Generator for %s: %s\n' % (cls, u''.join(text)))
return fields
View
@@ -4,7 +4,7 @@
import random
import urllib
-from library import lorem_ipsum, names
+from scaffolding.library import lorem_ipsum, names
from django.core.files import File
class Tube(object):
@@ -15,6 +15,11 @@ def __init__(self, **kwargs):
def __iter__(self):
return self
+
+ def set_up(self, cls, count, **kwargs):
+ """ This is a hook for doing validations
+ kwargs for future compatibility.
+ """
def next(self):
raise NotImplementedError('You need to implement your own next method.')
@@ -48,6 +53,8 @@ def __init__(self, values, **kwargs):
self.length = len(self.values)
def next(self):
+ if self.length == 0:
+ raise StopIteration
self.index += 1
return self.values[self.index % self.length]

1 comment on commit 2e6ff9d

Contributor

matthiask commented on 2e6ff9d Mar 14, 2012

Nur kurz als Visualisierung der Generator-Geschichte – der folgende Code ist äquivalent zu den bestehenden Tubes:

def StaticValue(value):
    while True:
        yield value

def RandomValue(lst):
    while True:
        yield random.choice(lst)

def EveryValue(lst):
    i = 0
    length = len(lst)
    while True:
        yield lst[i % length]
        i += 1

def AlwaysTrue():
    while True:
        yield True

def AlwaysFalse():
    while True:
        yield False

def RandInt(min, max):
    while True:
        yield random.randint(min, max)

def ForeignKey(queryset, chunksize=100):
    return EveryValue(queryset[:chunksize])

yield kann seit Python 2.5 auch return values haben, es ist möglich, Werte in einen Generator reinzuschreiben währenddem er schon "läuft". Bin am überlegen, ob es da nicht eine schöne Möglichkeit gäbe...

Please sign in to comment.