Skip to content

Commit

Permalink
pep8ified
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed May 12, 2012
1 parent 7ec2cd7 commit 25d0d67
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
*.egg-info
*.egg
build
dist
.*
2 changes: 0 additions & 2 deletions .travis.yml
@@ -1,13 +1,11 @@
language: python
python:
- "2.5"
- "2.6"
- "2.7"
- "3.2"
- "pypy"
# command to install dependencies
install:
- pip install . --use-mirrors
- pip install -r requirements.txt --use-mirrors
# command to run tests
script: nosetests
2 changes: 2 additions & 0 deletions django_utils/__init__.py
@@ -0,0 +1,2 @@


26 changes: 26 additions & 0 deletions django_utils/base_models.py
@@ -0,0 +1,26 @@
from django.db.models import base
from python_utils import converters


class ModelBase(base.ModelBase):
'''
Model base with more readable naming convention
Example:
Assuming the model is called `app.FooBarObject`
Default Django table name: `app_foobarobject`
Table name with this base: `app_foo_bar_object`
'''

def __new__(cls, name, bases, attrs):
class_ = base.ModelBase.__new__(cls, name, bases, attrs)
module_name = converters.camel_to_underscore(name)

app_label = class_.__module__.split('.')[-2]
db_table = '%s_%s' % (app_label, module_name)
if not getattr(class_._meta, 'proxy', False):
class_._meta.db_table = db_table

return class_

2 changes: 2 additions & 0 deletions django_utils/management/__init__.py
@@ -0,0 +1,2 @@


2 changes: 2 additions & 0 deletions django_utils/management/commands/__init__.py
@@ -0,0 +1,2 @@


132 changes: 132 additions & 0 deletions django_utils/management/commands/admin_autogen.py
@@ -0,0 +1,132 @@
from django.core.management.base import BaseCommand
from django.db.models.loading import get_models
from django.db import models

LIST_FILTER = (
models.DateField,
models.DateTimeField,
models.ForeignKey,
models.BooleanField,
)

SEARCH_FIELD = (
'name',
'slug',
)

DATE_HIERARCHY = (
'created_at',
'updated_at',
'joined_at',
)

PREPOPULATED_FIELDS = {
'slug': ('name',)
}


class Command(BaseCommand):

def handle(self, *args, **kwargs):
apps = []
self.models = []

installed_apps = dict((a.__name__.rsplit('.', 1)[0], a)
for a in models.get_apps())
for arg in args:
app = installed_apps.get(arg)
if app:
apps.append(app)
else:
self.models.append(arg.lower())

for app in apps:
self.handle_app(app, **kwargs)

def handle_app(self, app, **options):
models_dict = {}

for model in get_models(app):
name = model.__name__
field_names = []

if self.models and name.lower() not in self.models:
continue

models_dict[name] = model_dict = {
'list_display': [],
'list_filter': [],
'raw_id_fields': [],
'search_fields': [],
'prepopulated_fields': {},
'date_hierarchy': None,
}

parent_fields = model._meta.parents.values()

for field in model._meta.fields:
if field in parent_fields:
continue

field_names.append(field.name)
model_dict['list_display'].append(field.name)

if isinstance(field, LIST_FILTER):
if isinstance(field, models.ForeignKey):
related_objects = field.related.parent_model.objects
if related_objects.all()[:100].count() <= 100:
model_dict['list_filter'].append(field.name)
else:
model_dict['raw_id_fields'].append(field.name)
else:
model_dict['list_filter'].append(field.name)

if field.name in SEARCH_FIELD:
model_dict['search_fields'].append(field.name)

for field_name in DATE_HIERARCHY:
if field_name in field_names \
and not model_dict['date_hierarchy']:
model_dict['date_hierarchy'] = field_name

for k, vs in sorted(PREPOPULATED_FIELDS.iteritems()):
if field_name in field_names \
and not model_dict['date_hierarchy']:
model_dict['date_hierarchy'] = field_name

if k in field_names:
incomplete = False
for v in vs:
if v not in field_names:
incomplete = True
break

if not incomplete:
model_dict['prepopulated_fields'][k] = vs

print 'import models'
print 'from django.contrib import admin'

for name, model in sorted(models_dict.iteritems()):
print '\n\nclass %sAdmin(admin.ModelAdmin):' % name
for k, v in sorted(model.iteritems()):
if v:
if isinstance(v, (list, set)):
v = tuple(v)

row = ' %s = %r' % (k, v)
row_parts = []
while len(row) > 78:
pos = row.rfind(' ', 0, 78)
row_parts.append(row[:pos])
row = ' ' + row[pos:]

row_parts.append(row)

print '\n'.join(row_parts)

print '\n'
for name in sorted(models_dict):
print 'admin.site.register(models.%s, %sAdmin)' % (name, name)
print

1 change: 1 addition & 0 deletions django_utils/management/commands/settings.py
@@ -1,6 +1,7 @@
from django.core.management.base import BaseCommand
import pprint


class Command(BaseCommand):
help = '''Get a list of the current settings, any arguments given will be
used to match the settings name (case insensitive).
Expand Down
2 changes: 2 additions & 0 deletions django_utils/models.py
@@ -0,0 +1,2 @@


4 changes: 3 additions & 1 deletion django_utils/queryset.py
@@ -1,5 +1,6 @@
import gc


def queryset_iterator(queryset, chunksize=1000, getfunc=getattr):
'''''
Iterate over a Django Queryset ordered by the primary key
Expand All @@ -9,7 +10,8 @@ def queryset_iterator(queryset, chunksize=1000, getfunc=getattr):
memory. Using the iterator() method only causes it to not preload all the
classes.
Note that the implementation of the iterator does not support ordered query sets.
Note that the implementation of the iterator does not support ordered
query sets.
'''
pk = 0

Expand Down
151 changes: 151 additions & 0 deletions django_utils/view_decorators.py
@@ -0,0 +1,151 @@
import anyjson
from django import shortcuts as django_shortcuts
from django import http
from django.template import RequestContext
from django.contrib.auth import decorators


class ViewError(Exception):
pass


class UnknownViewResponseError(ViewError):
pass

REQUEST_PROPERTIES = {
'redirect': http.HttpResponseRedirect,
'permanent_redirect': http.HttpResponsePermanentRedirect,
'not_found': http.HttpResponseNotFound,
}


def _prepare_request(request, app, view):
'''Add context and extra methods to the request'''
request.context = RequestContext(request)
request.context['view'] = view
request.context['app'] = app

for k, v in REQUEST_PROPERTIES.iteritems():
setattr(request, k, v)

return request


def _process_response(request, response):
'''Generic response processing function, always returns HttpResponse'''

'''If we add something to the context stack, pop it after adding'''
pop = False

try:
if isinstance(response, (dict, list)):
if request.ajax:
output = json = anyjson.serialize(response)
callback = request.GET.get('callback', False)
if callback:
output = '%s(%s)' % (callback, json)
if request.GET.get('debug'):
title = 'Rendering %(view)r in module %(app)r' % (
request.context)

output = '''
<html>
<head>
<title>%s</title>
</head>
<body>
<textarea>%s</textarea>
</body>
</html>
''' % (title, output)
response = http.HttpResponse(output,
mimetype='text/html')
else:
response = http.HttpResponse(output,
mimetype='text/plain')

return response
else:
'''Add the dictionary to the context and let
render_to_response handle it'''
request.context.update(response)
response = None
pop = True

if isinstance(response, http.HttpResponse):
return response

elif isinstance(response, basestring):
if request.ajax:
return http.HttpResponse(response, mimetype='text/plain')
else:
return http.HttpResponse(response)

elif response is None:
render_to_response = django_shortcuts.render_to_response

return render_to_response(request.template,
context_instance=request.context)

else:
raise UnknownViewResponseError(
'"%s" is an unsupported response type' % type(response))
finally:
if pop:
request.context.pop()


def env(function=None, login_required=False):
'''
View decorator that automatically adds context and renders response
Keyword arguments:
login_required -- is everyone allowed or only authenticated users
Adds a RequestContext (request.context) with the following context items:
name -- current function name
Stores the template in request.template and assumes it to be in
<app>/<view>.html
'''

def _env(request, *args, **kwargs):
request.ajax = request.is_ajax() or bool(int(
request.REQUEST.get('ajax', 0)))
request.context = None
try:
name = function.__name__
app = function.__module__.split('.')[0]

request = _prepare_request(request, app, name)

if app:
request.template = '%s/%s.html' % (app, name)
else:
request.template = '%s.html' % name

response = function(request, *args, **kwargs)

return _process_response(request, response)
finally:
'''Remove the context reference from request to prevent leaking'''
try:
del request.context, request.template
for k, v in REQUEST_PROPERTIES.iteritems():
delattr(request, k)
except AttributeError:
pass

if function:
_env.__name__ = function.__name__
_env.__doc__ = function.__doc__
_env.__module__ = function.__module__
_env.__dict__ = function.__dict__

if login_required:
return decorators.login_required(_env)
else:
return _env
else:
return lambda f: env(f, login_required)

0 comments on commit 25d0d67

Please sign in to comment.