Skip to content

Commit

Permalink
merging
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed Dec 11, 2016
2 parents 886c963 + 26834fa commit 1d2a57f
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 138 deletions.
28 changes: 13 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,22 @@ python: 2.7
cache: pip

env:
- TOX_ENV=py26-django14
- TOX_ENV=py26-django15
- TOX_ENV=py26-django16
- TOX_ENV=py27-django14
- TOX_ENV=py27-django15
- TOX_ENV=py27-django16
- TOX_ENV=coveralls
- TOX_ENV=py27-django18
- TOX_ENV=py34-django15
- TOX_ENV=py34-django16
- TOX_ENV=py27-django19
- TOX_ENV=py27-django110
- TOX_ENV=py34-django18
- TOX_ENV=pypy-django14
- TOX_ENV=pypy-django15
- TOX_ENV=pypy-django16
- TOX_ENV=py34-django19
- TOX_ENV=py34-django110
- TOX_ENV=py35-django18
- TOX_ENV=py35-django19
- TOX_ENV=py35-django110
- TOX_ENV=py36-django18
- TOX_ENV=py36-django19
- TOX_ENV=py36-django110
- TOX_ENV=pypy-django18
- TOX_ENV=pypy3-django15
- TOX_ENV=pypy3-django16
- TOX_ENV=pypy3-django18
- TOX_ENV=coveralls
- TOX_ENV=pypy-django19
- TOX_ENV=pypy-django110

install:
- pip install --upgrade pip
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ Usage

To generate an admin for a given app:

./manage.py admin_generator <APP_NAME> >> <APP_NAME>/admin.py
./manage.py admin_generator APP_NAME >> APP_NAME/admin.py

To generate an admin for a given app with all models starting with user:

./manage.py admin_generator <APP_NAME> '^user' >> <APP_NAME>/admin.py
./manage.py admin_generator APP_NAME '^user' >> APP_NAME/admin.py

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__package_name__ = 'django-admin-generator'
__version__ = '1.5.0'
__version__ = '2.0.0'
__author__ = 'Rick van Hattem'
__author_email__ = 'Wolph@Wol.ph'
__description__ = '''Django Admin Generator is a management command to
Expand Down
74 changes: 43 additions & 31 deletions django_admin_generator/management/commands/admin_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import re
import sys
import six
import optparse
from django_utils.management.commands import base_command
from django.db import models

Expand Down Expand Up @@ -180,8 +179,7 @@ def name(self):
def _process_many_to_many(self, meta):
raw_id_threshold = self.raw_id_threshold
for field in meta.local_many_to_many:
related_model = getattr(field.related, 'related_model',
field.related.model)
related_model = self._get_related_model(field)
related_objects = related_model.objects.all()
if(related_objects[:raw_id_threshold].count() < raw_id_threshold):
yield field.name
Expand All @@ -193,12 +191,22 @@ def _process_fields(self, meta):
if name: # pragma: no cover
yield name

@classmethod
def _get_related_model(cls, field): # pragma: no cover
if hasattr(field, 'remote_field'):
related_model = field.remote_field.model
elif hasattr(field.related, 'related_model'):
related_model = field.related.related_model
else:
related_model = field.related.model

return related_model

def _process_foreign_key(self, field):
raw_id_threshold = self.raw_id_threshold
list_filter_threshold = self.list_filter_threshold
max_count = max(list_filter_threshold, raw_id_threshold)
related_model = getattr(field.related, 'related_model',
field.related.model)
related_model = self._get_related_model(field)
related_count = related_model.objects.all()
related_count = related_count[:max_count].count()

Expand Down Expand Up @@ -315,40 +323,48 @@ def _process(self):

class Command(base_command.CustomBaseCommand):
help = '''Generate a `admin.py` file for the given app (models)'''
option_list = base_command.CustomBaseCommand.option_list + (
optparse.make_option(
can_import_settings = True
requires_system_checks = True

def add_arguments(self, parser):
super(Command, self).add_arguments(parser)

parser.add_argument(
'-s', '--search-field', action='append',
default=SEARCH_FIELD_NAMES,
help='Fields named like this will be added to `search_fields`'
' [default: %default]'),
optparse.make_option(
' [default: %default]')
parser.add_argument(
'-d', '--date-hierarchy', action='append',
default=DATE_HIERARCHY_NAMES,
help='A field named like this will be set as `date_hierarchy`'
' [default: %default]'),
optparse.make_option(
' [default: %default]')
parser.add_argument(
'-p', '--prepopulated-fields', action='append',
default=PREPOPULATED_FIELD_NAMES,
help='These fields will be prepopulated by the other field.'
'The field names can be specified like `spam=eggA,eggB,eggC`'
' [default: %default]'),
optparse.make_option(
'-l', '--list-filter-threshold', type='int',
' [default: %default]')
parser.add_argument(
'-l', '--list-filter-threshold', type=int,
default=LIST_FILTER_THRESHOLD, metavar='LIST_FILTER_THRESHOLD',
help='If a foreign key has less than LIST_FILTER_THRESHOLD items '
'it will be added to `list_filter` [default: %default]'),
optparse.make_option(
'-r', '--raw-id-threshold', type='int',
'it will be added to `list_filter` [default: %default]')
parser.add_argument(
'-r', '--raw-id-threshold', type=int,
default=RAW_ID_THRESHOLD, metavar='RAW_ID_THRESHOLD',
help='If a foreign key has more than RAW_ID_THRESHOLD items '
'it will be added to `list_filter` [default: %default]'),
optparse.make_option(
'it will be added to `list_filter` [default: %default]')
parser.add_argument(
'-n', '--no-query-db', action="store_true", dest='no_query_db',
help='Don\'t query the database in order to decide whether '
'relationships are added to `list_filter`'),
)
can_import_settings = True
requires_system_checks = True
'relationships are added to `list_filter`')
parser.add_argument(
'app',
help='App to generate admin definitions for')
parser.add_argument(
'models', nargs='*',
help='Regular expressions to filter the models by')

def warning(self, message):
# This replaces the regular warning method from the CustomBaseCommand
Expand All @@ -357,16 +373,12 @@ def warning(self, message):
sys.stderr.write(message)
sys.stderr.write('\n')

def handle(self, *args, **kwargs):
def handle(self, app=None, *args, **kwargs):
super(Command, self).handle(*args, **kwargs)

installed_apps = dict(get_apps())

# Make sure we always have args
if not args:
args = [False]

app = installed_apps.get(args[0])
app = installed_apps.get(app)
if not app:
self.warning('This command requires an existing app name as '
'argument')
Expand All @@ -376,8 +388,8 @@ def handle(self, *args, **kwargs):
sys.exit(1)

model_res = []
for arg in args[1:]:
model_res.append(re.compile(arg, re.IGNORECASE))
for model in kwargs.get('models', []):
model_res.append(re.compile(model, re.IGNORECASE))

self.handle_app(app, model_res, **kwargs)

Expand Down
61 changes: 26 additions & 35 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,37 @@
import os
import sys
import setuptools

from django_admin_generator import metadata
from setuptools.command.test import test as TestCommand
# To prevent importing about and thereby breaking the coverage info we use this
# exec hack
about = {}
with open('django_admin_generator/__about__.py') as fp:
exec(fp.read(), about)


if os.path.isfile('README.rst'):
long_description = open('README.rst').read()
else:
long_description = 'See http://pypi.python.org/pypi/%s/' % (
metadata.__package_name__)


class PyTest(TestCommand):
def finalize_options(self):
TestCommand.finalize_options(self)
self.test_args = []
self.test_suite = True
about['__package_name__'])

def run_tests(self):
# import here, cause outside the eggs aren't loaded
import pytest
errno = pytest.main(self.test_args)
sys.exit(errno)

setuptools.setup(
name=metadata.__package_name__,
version=metadata.__version__,
author=metadata.__author__,
author_email=metadata.__author_email__,
description=metadata.__description__,
url=metadata.__url__,
license='BSD',
packages=setuptools.find_packages(),
long_description=long_description,
tests_require=['pytest'],
cmdclass={'test': PyTest},
py_modules=['django_admin_generator'],
classifiers=['License :: OSI Approved :: BSD License'],
install_requires=[
'django-utils2>=1.7.1',
'six',
]
)
if __name__ == '__main__':
setuptools.setup(
name=about['__package_name__'],
version=about['__version__'],
author=about['__author__'],
author_email=about['__author_email__'],
description=about['__description__'],
url=about['__url__'],
license='BSD',
packages=setuptools.find_packages(),
long_description=long_description,
install_requires=[
'django-utils2>=2.2.1',
'six',
],
tests_require=['pytest'],
setup_requires=['pytest-runner'],
classifiers=['License :: OSI Approved :: BSD License'],
)

23 changes: 18 additions & 5 deletions test_project/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@
import os
import sys

if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')

from django.core.management import execute_from_command_line

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
assert django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)

0 comments on commit 1d2a57f

Please sign in to comment.