django-groundwork,它不实现具体的功能,而是扩展了manage.py 的命令,使得通过命令行可以生成一些代码/文件。根据你的模型自动生成模板、view、url等。 将下载好的groundwork放到与APP同级的目录,在setting.py 中添加'django-groundwork'

网上流传的都不太适合我使用的1.5.3版本,所以个人对其进行了小修改。

groundwork.py:

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
from django.core.management.base import BaseCommand, CommandError
from django.db import models
from placeholders import *
import os
class Command(BaseCommand):
def handle(self, *args, **options):
"Usage : manage.py groundwork <app> <model>"
PROJECT_ROOT = os.getcwd()+r'/'+args[0]
PROJECT_MROOT = os.getcwd()
TEMPLATE_DIR = os.path.join ( PROJECT_ROOT , 'templates')
print PROJECT_ROOT
print TEMPLATE_DIR
try:
app = args[1] # App name is the first parameter
model_names = args[2:] # Models which need to be scaffolded will follow
model_instances = [ models.get_model(app, x) for x in model_names ]
# url config
urls = URL_IMPORTS
# Generate CRUD urls for each model
for model_instance in model_instances:
urls += URL_CRUD_CONFIG % {'model':model_instance._meta.object_name.lower(), 'modelClass': model_instance._meta.object_name }
urls += URL_END
# write to urls.py
f = open( os.path.join (PROJECT_MROOT , app, 'urls.py') , 'w')
f.write(urls)
f.close()
# append to root urlconf
f = open( os.path.join (PROJECT_ROOT , 'urls.py') , 'a')
f.write( "nurlpatterns += patterns ('',n (r'^%(app)s/', include('%(app)s.urls')),n)n" % {'app': app } )
f.close()
# forms
forms_content = FORMS_IMPORTS
print forms_content
for model_instance in model_instances:
forms_content += FORMS_MODELFORM_CONFIG % { 'modelClass' : model_instance._meta.object_name }
formspath = os.path.join (PROJECT_MROOT, app, 'forms.py')
f = open( formspath , 'w')
f.write(forms_content)
f.close()
# views
views_content = VIEWS_IMPORTS
for model_instance in model_instances:
views_content += VIEWS_CREATE
views_content += VIEWS_LIST
views_content += VIEWS_VIEW
views_content += VIEWS_UPDATE
views_content = views_content % {'model':model_instance._meta.object_name.lower(), 'modelClass': model_instance._meta.object_name, 'app': app }
# write to views.py
viewspath = os.path.join (PROJECT_MROOT, app, 'views.py')
f = open( viewspath, 'w')
f.write(views_content)
f.close()
# Templates
template_dir = os.path.join(TEMPLATE_DIR, app )
if not os.path.exists(template_dir):
os.makedirs(template_dir)
print "Generate base template? [Y/N]?"
yn = raw_input()
if yn.lower() == 'y':
f = open(os.path.join(TEMPLATE_DIR, 'base.html') , 'w')
f.write(TEMPLATES_BASE)
f.close()
for model_instance in model_instances:
f = open(os.path.join( TEMPLATE_DIR, app, 'create_%s.html' % (model_instance._meta.object_name.lower()) ) ,'w')
f.write( TEMPLATES_CREATE % { 'modelClass' : model_instance._meta.object_name } )
f.close()
f = open(os.path.join( TEMPLATE_DIR, app, 'list_%s.html' % (model_instance._meta.object_name.lower()) ) ,'w')
f.write( TEMPLATES_LIST % { 'modelClass' : model_instance._meta.object_name ,'model' : model_instance._meta.object_name.lower(), 'app' : app} )
f.close()
f = open(os.path.join( TEMPLATE_DIR, app, 'edit_%s.html' % (model_instance._meta.object_name.lower()) ) ,'w')
f.write( TEMPLATES_EDIT % { 'modelClass' : model_instance._meta.object_name } )
f.close()
f = open(os.path.join( TEMPLATE_DIR, app, 'view_%s.html' % (model_instance._meta.object_name.lower()) ) , 'w')
f.write( TEMPLATES_VIEW % { 'modelClass' : model_instance._meta.object_name, 'model' : model_instance._meta.object_name.lower()} )
f.close()
# settings
f = open(os.path.join(PROJECT_ROOT, 'settings.py'), 'a')
f.write( "nimport osnTEMPLATE_DIRS += (os.path.join( os.path.dirname(__file__), 'templates') ,)n")
f.close()
except:
print "Usage : manage.py groundwork <app> <model>"

placeholders.py(1.5以后版本<herf url后面的view必须用引号引起来):

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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
URL_IMPORTS = """
from django.conf.urls.defaults import *
from models import *
from views import *
urlpatterns = patterns('',
"""
URL_CRUD_CONFIG = """
(r'%(model)s/create/$', create_%(model)s),
(r'%(model)s/list/$', list_%(model)s ),
(r'%(model)s/edit/(?P<id>[^/]+)/$', edit_%(model)s),
(r'%(model)s/view/(?P<id>[^/]+)/$', view_%(model)s),
"""
URL_END = """
)
"""
# --------------------- #
# forms.py file section #
# --------------------- #
FORMS_IMPORTS = """
from django import forms
from models import *
"""
FORMS_MODELFORM_CONFIG = """
class %(modelClass)sForm(forms.ModelForm):
class Meta:
model = %(modelClass)s
# exclude = [] # uncomment this line and specify any field to exclude it from the form
def __init__(self, *args, **kwargs):
super(%(modelClass)sForm, self).__init__(*args, **kwargs)
"""
# --------------------- #
# views.py file section #
# --------------------- #
VIEWS_IMPORTS = """
# Create your views here.
from django import forms
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.template.loader import get_template
from django.core.paginator import Paginator
from django.core.urlresolvers import reverse
# app specific files
from models import *
from forms import *
"""
VIEWS_CREATE = """
def create_%(model)s(request):
form = %(modelClass)sForm(request.POST or None)
if form.is_valid():
form.save()
form = %(modelClass)sForm()
t = get_template('%(app)s/create_%(model)s.html')
c = RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
VIEWS_LIST = """
def list_%(model)s(request):
list_items = %(modelClass)s.objects.all()
paginator = Paginator(list_items ,10)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
list_items = paginator.page(page)
except :
list_items = paginator.page(paginator.num_pages)
t = get_template('%(app)s/list_%(model)s.html')
c = RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
VIEWS_UPDATE = """
def edit_%(model)s(request, id):
%(model)s_instance = %(modelClass)s.objects.get(id=id)
form = %(modelClass)sForm(request.POST or None, instance = %(model)s_instance)
if form.is_valid():
form.save()
t=get_template('%(app)s/edit_%(model)s.html')
c=RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
VIEWS_VIEW = """
def view_%(model)s(request, id):
%(model)s_instance = %(modelClass)s.objects.get(id = id)
t=get_template('%(app)s/view_%(model)s.html')
c=RequestContext(request,locals())
return HttpResponse(t.render(c))
"""
# ------------------------- #
# templates.py file section #
# ------------------------- #
TEMPLATES_CREATE = """
{%% extends "base.html" %%}
{%% block title %%} %(modelClass)s - Create {%% endblock %%}
{%% block heading %%}<h1> %(modelClass)s - Create </h1> {%% endblock %%}
{%% block content %%}
<table>
<form action="" method="POST"> {%% csrf_token %%}
{{form}}
<tr>
<td colspan="2" align="right"><input type="submit" value="Create"/></td>
</tr>
</form>
</table>
{%% endblock %%}
"""
TEMPLATES_LIST = """
{%% extends "base.html" %%}
{%% block title %%} <h1> %(modelClass)s </h1><h2> List </h2> {%% endblock %%}
{%% block heading %%}
<h1> %(modelClass)s</h1>
<h2> List Records</h2>
{%% endblock %%}
{%% block content %%}
<table>
<thead>
<tr><th>Record</th><th colspan="3">Actions</th></tr>
{%% for item in list_items.object_list %%}
<tr><td> {{item}}</td> <td><a href="{%% url "%(app)s.views.view_%(model)s" item.id %%}">Show</a> </td> <td><a href="{%% url "%(app)s.views.edit_%(model)s" item.id %%}">Edit</a></tr>
{%% endfor %%}
<tr><td colspan="3"> <a href="{%% url "%(app)s.views.create_%(model)s" %%}">Add New</a></td></tr>
</table>
<div align="center">
{%% if list_items.has_previous %%}
<a href="?page={{ list_items.previous_page_number }}">Previous</a>
{%% endif %%}
<span class="current">
Page {{ list_items.number }} of {{ list_items.paginator.num_pages }}.
</span>
{%% if list_items.has_next %%}
<a href="?page={{ list_items.next_page_number }}">Next</a>
{%% endif %%}
</div>
{%% endblock %%}
"""
TEMPLATES_EDIT = """
{%% extends "base.html" %%}
{%% block title %%} %(modelClass)s - Edit {%% endblock %%}
{%% block heading %%} <h1> %(modelClass)s</h1><h2> Edit </h2> {%% endblock %%}
{%% block content %%}
<table>
<form action="" method="POST"> {%% csrf_token %%}
{{form}}
<tr>
<td colspan="2" align="right"><input type="submit" value="Save"/></td>
</tr>
</form>
</table>
{%% endblock %%}
"""
TEMPLATES_VIEW = """
{%% extends "base.html" %%}
{%% block title %%} %(modelClass)s - View {%% endblock %%}
{%% block heading %%} <h1> %(modelClass)s</h1><h2>View</h2> {%% endblock %%}
{%% block content %%}
<table>
{{ %(model)s_instance }}
</table>
{%% endblock %%}
"""
TEMPLATES_BASE = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta name="description" content=""/>
<meta name="keywords" content="" />
<meta name="author" content="" />
<title>
{% block title %} {% endblock %}
</title>
<style type="text/css">
html * { padding:0; margin:0; }
body * { padding:10px 20px; }
body * * { padding:0; }
body { font:small sans-serif; }
body>div { border-bottom:1px solid #ddd; }
h1 { font-weight:normal; }
h2 { margin-bottom:.8em; }
h2 span { font-size:80% ; color:#666; font-weight:normal; }
h3 { margin:1em 0 .5em 0; }
h4 { margin:0 0 .5em 0; font-weight: normal; }
td {font-size:1em; padding:3px 17px 2px 17px;}
ul { margin-left: 2em; margin-top: 1em; }
#summary { background: #e0ebff; }
#summary h2 { font-weight: normal; color: #666; }
#explanation { background:#eee; }
#content { background:#f6f6f6; }
#summary table { border:none; background:transparent; }
</style>
</head>
<body>
<div id="summary">
{% block heading %}
{% endblock %}
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
<div id="explanation" align="center">
django-groundwork
</div>
</body>
</html>
"""

安装后,使用python manage.py help可以看到,列出的可用命令中多了一个groundwork。其语法是:

1
python manage.py groundwork appname ModelName1 ModelName2

修改后:

1
python manage.py groundwork projectname appname ModelName1 ModelName2

此时运行开发服务器(python manage.py runserver),就可以访问下面的地址:

http://localhost:8000/appname/ModelName/list/访问ModelName列表,并链接到create,edit,view等界面。

注意,用此APP需要先定义好模型,否则后面每次使用时候都会在setting.py中添加冗余数据。