1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 | #!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Title: Port to newforms-admin
Project: Developer tools
Author: Will Hardy (http://willhardy.com.au)
Date: June 2008
Usage: ./manage.py port2nfa > admin.py
To do: * inline classes
* prepopulate_from
"""
import sys
from django.db import models
from django.core.management.base import BaseCommand
from django import utils
from django.contrib import admin
# Redefine repr to be able to handle proxy objects within lists, tuples and dicts
_python_repr = repr
def repr(obj):
if isinstance(obj, list):
return u"[%s]" % ", ".join([ repr(item) for item in obj ])
elif isinstance(obj, tuple):
return u"(%s, )" % ", ".join([ repr(item) for item in obj ])
elif isinstance(obj, dict):
items = []
for key, value in obj.items():
items.append(u"%s: %s" % (repr(key), repr(value)))
return "{%s}" % ", ".join(items)
elif obj.__class__.__name__ == "__proxy__":
return "_(%s)" % repr(unicode(obj))
return _python_repr(obj)
class Command(BaseCommand):
help = 'Generates a python script to define the admin site from an oldforms admin definition..'
args = '[appname ...]'
def handle(self, *app_labels, **options):
from django.db.models import get_app, get_apps, get_models
if len(app_labels) == 0:
app_list = get_apps()
else:
app_list = [get_app(app_label) for app_label in app_labels]
# Get a list of all the relevant models
models = []
for app in app_list:
models += get_models(app)
# A dictionary to store required imports
imports = {}
# process the models to create a list of entries, and update the imports dictionary
entries = get_entries(models, imports)
# Structure the full output
lines = Lines()
lines += 'from django.contrib import admin'
lines += 'from django.utils.translation import ugettext_lazy as _'
lines += get_import_lines(imports)
lines.add_empty_line()
lines += entries
lines += "site = admin.AdminSite()"
lines += [ "site.register(%s, %sAdmin)" % (model, model) for model in imports.keys() ]
print lines
def get_entries(models, imports):
entries = []
for model in models:
entry = "\n".join(get_model_lines(model))
if entry:
if model.__name__ in imports:
sys.stderr.write("A model with this name has already been processed! Skipping %s" % model.__name__)
else:
entries.append(entry)
imports[model.__name__] = model.__module__
return entries
def get_model_lines(model):
" Returns a newforms-admin definition and registration for this model. "
lines = Lines()
admin_attributes = hasattr(model, "Admin") and model.Admin or model._meta.admin
if admin_attributes:
lines += "class %sAdmin(admin.ModelAdmin):" % model.__name__
lines += get_basic_fields(model, admin_attributes)
lines += get_prepopulated_fields(model)
if len(lines) == 1:
lines += ' pass'
lines.add_empty_line()
return lines
def get_basic_fields(model, admin_attributes):
lines = Lines()
if hasattr(model, "Admin") and model.Admin:
for key,value in model.Admin.__dict__.items():
if not key.startswith("__"):
lines += " %s = %s" % (key, repr(value))
if model._meta.admin:
from django.db.models.options import AdminOptions
default_object = AdminOptions()
for key,value in model._meta.admin.__dict__.items():
if value and key not in ('manager', ) and value != getattr(default_object, key):
lines += " %s = %s" % (key, repr(value))
return lines
def get_prepopulated_fields(model):
fields = {}
for field in model._meta.fields:
if hasattr(field, 'prepopulate_from') and field.prepopulate_from:
fields[field.name] = field.prepopulate_from
if fields:
return "prepopulated_fields = %s" % repr(fields)
def get_import_lines(imports):
" Takes a dictionary of imports and formats them nicely. "
# Create a dictionary to combine imported objects from the same module
imports_dict = {}
for key,value in imports.items():
if value in imports_dict:
imports_dict[value].append(key)
else:
imports_dict[value] = [key]
# Generate the final formatted output
return [ 'from %s import %s' % (mod, ", ".join(obj)) for mod,obj in imports_dict.items() ]
# HELPER CLASSES
################################################################################
class Lines(list):
def add_empty_line(self):
self.append("")
def add_line(self, value):
self.append(value)
def __unicode__(self):
return u"\n".join(self)
def __str__(self):
return "\n".join(self)
def __iadd__(self, value):
if isinstance(value, basestring):
value = [ value ]
if value:
return super(Lines, self).__iadd__(value)
else:
return self
|
Comments