利用Djangoadmin完成更多任务剖析Word格式.docx
《利用Djangoadmin完成更多任务剖析Word格式.docx》由会员分享,可在线阅读,更多相关《利用Djangoadmin完成更多任务剖析Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
![利用Djangoadmin完成更多任务剖析Word格式.docx](https://file1.bdocx.com/fileroot1/2022-11/23/5a045dfe-2501-45c8-acf3-8a1a68d03d27/5a045dfe-2501-45c8-acf3-8a1a68d03d271.gif)
fromdjango.conf.urls.defaultsimport*
#Uncommentthenexttwolinestoenabletheadmin:
fromdjango.contribimportadmin
admin.autodiscover()
urlpatterns=patterns('
'
#Uncommentthenextlinetoenabletheadmin:
(r'
^admin/(.*)'
admin.site.root),
)
本文使用的软件版本
*DjangoV1.0.2
*SQLiteV3
*PythonV2.4-2.6(Django尚不支持PythonV3)
*IPython(用作样例输出)
DjangoObject-RelationalMapper(ORM)支持许多数据库后端,但是SQLite是最简单的安装方式,许多操作系统都附带SQLite。
这些样例也适用于其他后端。
有关Django支持的数据库列表,请参见参考资料。
Django提供一个快速方式,可以使用独立代码设置工作环境:
运行pythonmanage.pyshell。
本文中的所有代码样例都假设已经调用了该环境。
在Djangolingo中,假设如下:
*这是一个名为more_with_admin的Django项目。
*more_with_admin项目包含一个名为examples的应用程序。
examples应用程序模拟基本的类博客文档系统,这些文档中还有多个评论(或没有)。
所有命令行样例都来自projectroot——more_with_admin主目录。
您还需要将django.contrib.admin应用程序添加到settings.INSTALLED_APPS。
在继续下一步前,建议计划扩展admin的用户熟悉一下源代码。
对于支持快捷键和符号链接的操作系统,创建一个指向admin应用程序的快捷键或符号链接会很有用。
admin包含在Django包中。
假如已经使用安装工具安装了admin,则它位于django/contrib/admin下的site-packages中。
以下是一个项目到Djangoadmin源的符号链接样例,您可以根据操作系统和Django安装的位置定制,以便更轻松的复制和引用:
$ln-s/path/to/Python/install/site-packages/django/contrib/adminadmin-source
admin.autodiscover()方法迭代设置.INSTALLED_APPS中的每个应用程序,并查找名为admin.py的文件。
该文件通常位于应用程序目录的最上方,与models.py级别一样。
样例应用程序需要清单2中提供的models.py。
相应的admin.py如下所示。
清单2.该应用程序的样例models.py
fromdjango.dbimportmodels
classDocument(models.Model):
'
ADocumentisablogpostorwikientrywithsometextcontent'
name=models.CharField(max_length=255)
text=models.TextField()
def__unicode__(self):
returnself.name
classComment(models.Model):
ACommentissometextaboutagivenDocument'
document=models.ForeignKey(Document,related_name='
comments'
现在,您可以通过运行Django开发服务器调用admin:
pythonmanage.pyrunserver
admin可从默认位置http:
//localhost:
8000/admin/获取。
登录之后,您可以看到基本的admin屏幕,如下所示。
图1.基本的Djangoadmin屏幕
基本的Djangoadmin屏幕
更改admin.py中的代码
与Django应用程序中的其他文件不同,如果使用Django开发Web服务器更改admin.py,您可能需要手动重启服务器。
注意,您的模型现在尚不可用,因为您还没有创建admin.py。
清单3展示的代码让您能在admin中使用模型。
清单3.样例admin.py
frommore_with_admin.examplesimportmodels
classDocumentAdmin(admin.ModelAdmin):
pass
classCommentAdmin(admin.ModelAdmin):
admin.site.register(models.Document,DocumentAdmin)
admin.site.register(models.Comment,CommentAdmin)
现在如果您在admin中重载主页,您将看到可用的新模型,如下所示。
图2.可以支持定制模型的Djangoadmin
带有定制模型的Djangoadmin屏幕
回页首
定制admin模型页面
admin文件夹中的目录名称
注意,我使用模型的小写名称。
这与生成URL时处理普通admin页面的方式是一致的。
Django调用支持URL的表格slugs。
如果您不确定给定的模型应该使用哪个slug,可以在创建目录之前先浏览admin并留意出现在URL中的名称。
理解在不修改Django源代码的情况下如何定制admin的关键在于,记住admin像其他程序一样只是一个普通的Django应用程序。
最重要的一点是,这意味着可以使用Django模版继承系统。
Django的模版搜索顺序总是将您自己项目的模版排在其他系统之前。
此外,admin在恢复到默认情况前,会尝试搜索匹配每个模型的硬编码模版。
这为轻松定制提供了一个扩展点。
首先,确保Django通过编辑项目的settings.py来查看您的模版目录。
清单4.编辑settings.py以查看模版目录
TEMPLATE_DIRS=(
"
/path/to/project/more_with_admin/templates"
/path/to/project/more_with_admin/examples/templates"
然后在项目中创建以下目录:
$mkdirtemplates/admin/examples/document/
$mkdirtemplates/admin/examples/comment/
Djangoadmin的特殊行为将检查目录和应用程序名称(这里是examples),然后是模型的名称(document和comment),然后才能使用系统模版呈现该管理页面。
重写单个模型添加/编辑页面
admin用来添加和编辑模型实例的页面名称是change_form.html。
首先在Document模型目录中创建一个名为templates/admin/examples/document/change_form.html的页面,然后将Django模版继承线置入其中:
{%extends"
admin/change_form.html"
%}。
现在可以进行定制了。
花一些时间熟悉实际的admin/change_form.html的内容。
它很合理地将一些可以重写的模板块组织到一起,但是有些定制可能需要大量复制模块。
不过,使用基于块的模板重写总是比复制整个页面要好。
您想对添加/编辑页面执行哪种定制?
对于系统中的每个Document,您应该展示5个最近评论的预览。
首先,创建一些样例内容。
清单5.使用Djangoshell创建带几个评论的样例Document
$pythonmanage.pyshell
In[1]:
fromexamplesimportmodels
In[2]:
d=models.Document.objects.create(name='
Testdocument'
text='
Thisisatestdocument.'
In[3]:
forcinrange(0,10):
...:
models.Comment.objects.create(text='
Commentnumber%s'
%c,document=d)
现在,admin列表页面展示一个Document。
选择该Document打开默认的添加/编辑页面,如下所示。
图3.带有Document的默认添加/编辑页面
默认的添加/编辑页面
注意,相关评论不显示。
在admin中显示相关模型的标准方法是使用强大的Inline类。
Inline类允许admin用户在单个页面编辑或添加多个相关模型。
要查看运行的inline,按照清单6编辑应用程序admin.py。
清单6.向Documentadmin添加相关模型评论
classCommentInline(admin.TabularInline):
model=models.Comment
inlines=[CommentInline,]
图4展示了添加TabularInline控件之后新的添加/编辑页面。
图4.将评论模型作为Inline添加之后的添加/编辑页面
将评论模型作为Inline添加之后的添加/编辑页面
这无疑非常强大,但是如果只想快速预览评论的话就没必要这样做了。
这里您可以采取两种方法。
一种是使用Djangoadminwidget接口编辑与inline关联的HTMLwidget;
Django文档详细描述了widget。
另一种方法是直接修改添加/编辑页面。
如果不希望使用任何特定于admin的功能,那么该方法非常有用。
如果不允许编辑评论(可能是由于用户没有足够的权限),但是又想让用户看到评论,那么可以修改change_form.html。
Djangoadmin提供的变量
要在模型实例页面添加功能,您需要了解admin已经可以使用什么数据。
两个键变量的说明如下。
表1.定制admin模版需要的变量
变量说明
object_id这是编辑对象时需要的主键。
如果要定义特定的实例页面(比如Document),那么使用该键就够了。
content_type_id如果要重写多种模型页面,使用该变量查询ContentTypes框架来获取模型的名称。
更多有关内容类型的信息,请参见参考资料。
为admin页面中的内容创建模板标记
列出无法直接输入Django模板的相关评论查询代码。
最佳的解决方案是使用模板标记。
首先,创建模板标记目录and__init__.py文件:
$mkdirexamples/templatetags/
$touchexamples/templatetags/__init__.py
创建一个名为examples/templatetags/example_tags.py的新文件,并添加以下代码。
清单7.根据给定DocumentID检索评论的模板标签
fromdjangoimporttemplate
fromexamplesimportmodels
register=template.Library()
@register.inclusion_tag('
comments.html'
defdisplay_comments(document_id):
document=models.Document.objects.get(id__exact=document_id)
comments=models.Comment.objects.filter(document=document)[0:
5]
return{'
:
comments}
由于这是一个包含标签,您需要创建相应的模板文件:
comments.html。
编辑examples/templates/comments.html文件并输入清单8中的代码。
清单8.显示评论预览集的模板
{%forcommentincomments%}
<
blockquote>
{{comment.text}}<
/blockquote>
{%endfor%}
现在可以将它添加到admin页面了。
在admin.py中注释掉对CommentInline的引用,并按照清单9更改change_form.html的本地版本。
清单9.在添加/编辑页面包含模板标签
%}
{%loadexample_tags%}
{%blockafter_field_sets%}
{%ifobject_id%}{%display_commentsobject_id%}{%endif%}
{%endblock%}
在使用前检查object_id的存在很重要,因为change_form.html还可以用来创建新实例,在这种情况下object_id不可用。
after_field_sets块只是admin中提供的众多扩展点之一。
其他请参考change_form.html源页面。
图5展示了更新后的表格。
图5.包含模板标记之后的添加/编辑页面
包含模板标记之后的添加/编辑页面
修改admin行为
模板重写只能做这么多了。
如果您想更改admin的实际流和行为怎么办呢?
修改源代码不是不可能,但是那会让您受制于更新时使用的特定Django版本。
重写AdminModel方法
默认情况下,在admin中单击Save将用户带回到列表页面。
通常这没有问题,但是如果您想直接到admin外部的对象预览页面,那应该怎么办?
在开发内容管理系统(CMS)时这种情况很常见。
提供get_absolute_url()方法
清单10假设已经修改了Document以包含get_absolute_url()方法,该方法是Django模型指定规范表示的推荐方法。
如果指定了规范表示,Djangoadmin还在该模型的每个页面上放置一个有用的Viewonsite按钮。
admin应用程序中的大部分功能都附加到admin.ModelAdmin类。
这是该对象从admin.py中继承的类。
您可以重写许多许多公开方法。
类定义请查看admin-source/options.py中的源代码。
有两种方法可以更改Save按钮的行为:
您可以重写admin.ModelAdmin.response_add,该按钮负责保存后的实际重定向;
还可以重写admin.ModelAdmin.change_view。
后一种方式更为简单。
清单10.保存事件之后重写指向用户的页面
classDocumentAdmin(admin.ModelAdmin):
defchange_view(self,request,object_id,extra_context=None):
result=super(DocumentAdmin,self).change_view(request,object_id,extra_context)
document=models.Document.objects.get(id__exact=object_id)
ifnotrequest.POST.has_key('
_addanother'
)and
notrequest.POST.has_key('
_continue'
):
result['
Location'
]=document.get_absolute_url()
returnresult
现在用户单击Save时,他们将被指向预览页面,而不是展示所有Documents的列表页面。
使用signals向admin添加功能
signals是Django中较少使用的功能,它可以提高代码的模块化程度。
signals定义保存模型或加载模板的事件,无论它在哪里运行,Django项目都可以侦听到并对它做出反应。
这意味着您可以轻松的提高应用程序的行为,而无需直接修改它们。
admin提供了一个应用程序开发人员经常想修改的功能:
通过django.contrib.auth.models.User类管理用户。
Django用户往往只能添加或修改admin,这使得这个有用的类很难定制。
想象一下,您希望每次创建一个新的User对象时,站点管理员都能收到一封电子邮件。
因为User模块无法直接在项目中使用,实现该目标的唯一方法似乎是子类化User或者使用间接方法,比如创建虚拟配置文件对象进行修改。
清单11展示了在保存User实例时添加运行的函数有多么简单。
signals通常被添加到models.py。
清单11.添加新用户时使用Djangosignals进行通知
fromdjango.db.modelsimportsignals
fromdjango.contrib.auth.modelsimportUser
fromdjango.core.mailimportsend_mail
[...]
defnotify_admin(sender,instance,created,**kwargs):
Notifytheadministratorthatanewuserhasbeenadded.'
ifcreated:
subject='
Newusercreated'
message='
User%swasadded'
%instance.username
from_addr='
no-reply@'
recipient_list=('
admin@'
)
send_mail(subject,message,from_addr,recipient_list)
signals.post_save.connect(notify_admin,sender=User)
post_savesignal由Django提供,每次保存或创建模型时都会激活。
connect()方法带有两个参数:
一个回调参数(notify_admin)和sender参数,后者指定该回调只关注User模型的保存事件。
在回调中,post_savesignal传递发送方(模型类)、该模型的实例和提示是否刚刚创建了实例的布尔值。
在本例中,如果创建了User,该方法将发送一封电子邮件;
否则不执行任何操作。
有关其他Django提供的signals列表,请参见参考资料,以及介绍如何编写signals的文档。
进一步修改:
添加低级权限
为什么blank=True?
如果不是文本字段,很难看出ForeignKey字段应该设置为blank=True。
在本例中,Djangoadmin使用blank而不是null决定了保存模型前是否必须手动设置值。
如果您仅仅提供null=True(或者干脆不设置),那么Djangoadmin在保存前将强制用