Django admin 的 9 个技巧
Tip 1:Django admin 后台不限于用 Django 开发的网站
虽然 Django admin 管理界面可以非常友好的用在 Django 项目的其它部分,它同样可以很容易用于其它像传统的数据库或具有一个可怕的的管理界面的网站。而且这也是评估 Django 是否会满足您的需求的最佳途径。
你需要做的仅是:
在你的 Django 项目中建立一个新的应用,并确保你已经连接好传统数据库 ,通过 settings.py 文件中的 DATABASES 的设置。
将你的数据表定义为 Django 的模型。正如它的名字所表述的,manage.py inspectdb 是一个非常有用的命令:检测现有的数据库,并打印出自动生成的 Django 模型。
创建 admin.py 文件,并放在那里,唉,管理相关的。稍后将详细说明这个。
说到我们的动物“的网站,是由进屎的脑袋写出来的,所以管理界面看起来像……你知道的,不是很好。为了解决这个问题,我们通过几个 Django 模型重构了数据库结构,实现一个简单的管理界面:
# models.py
class Picture(models.Model):
DOG = 1
CAT = 2
ANIMAL_KIND_CHOICES = (
(DOG, 'dog'),
(CAT, 'cat'),
)
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, related_name='pictures')
animal_kind = models.IntegerField(choices=ANIMAL_KIND_CHOICES)
photo = models.ImageField(upload_to='animals')
is_promoted = models.BooleanField(default=False)
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
class Comment(models.Model):
author = models.ForeignKey(Author, related_name='comments')
picture = models.ForeignKey(Picture, related_name='comments')
comment = models.TextField()
editors_note = models.TextField()
# admin.py
class PictureAdmin(admin.ModelAdmin):
list_display_fields = ('photo', 'animal_kind', 'author', 'is_promoted', )
class AuthorAdmin(admin.ModelAdmin):
list_display_fields = ('name', 'email', )
class CommentAdmin(admin.ModelAdmin):
list_display_fields = ('picture', 'author', )
Tip #2: 按你喜欢的方式筛选你的数据
很多人使用 Django admin 后台对指定字段进行筛选。要知道,把一个字段名放到 list_filter 列表里就可以了。同时它也非常容易地创建一个自定义过滤器!
假如最终你决定要推广所有有 100+ 的帖子的作者。但是,我们如何区分它们?让我们创建一个过滤器,并把它添加到我们的变更列表。
class ProductiveAuthorsFilter(admin.SimpleListFilter):
parameter_name = 'is_productive'
title = 'Productive author'
YES, NO = 1, 0
# Number of comments for an author to be considered a productive one
THRESHOLD = 100
def lookups(self, request, model_admin):
return (
(self.YES, 'yes'),
(self.NO, 'no'),
)
def queryset(self, request, queryset):
qs = queryset.annotate(Count('comments'))
# Note the syntax. This way we avoid touching the queryset if our
# filter is not used at all.
if self.value() == self.YES:
return qs.filter(comments__count__gte=self.THRESHOLD)
if self.value() == self.NO:
return qs.filter(comments__count__lt=self.THRESHOLD)
return queryset
class PictureAdmin(admin.ModelAdmin):
list_filters = [..., ProductiveAuthorsFilter]
现在,我们可以很容易地选出我们的核心作者。那么我们如何开始向他们推广呢?让我们进入下一部分。
Tip #3:添加动作(操作函数)到 ‘actions’
这可是内容管理者的天赐之物。还记得在每个模型的列表顶部的“动作”工具栏不?我们是不是非常方便的先选择一些图片,然后只需单击一下就“推广”给作者了?现在让我们来实现它:
class PictureAdmin(admin.ModelAdmin):
actions = ['promote', ]
def promote(self, request, queryset):
queryset.update(is_promoted=True)
self.message_user(request, 'The posts are promoted')
promote.short_description = 'Promote the pictures'
就是这样!不用再一个挨一个的打开每个表单!另外,它很容易进一步增加我们的动作,例如,添加一个过渡表单。关于这点,Django 文档 有段非常棒的讲解。
Tip #4: 搜索你需要的所有字段
好吧,过滤器是很酷,但让我们关注了一下就搜索工具。在几乎所有的安装我见过的搜索框是用来在一个模型中的字段搜索。但是,当你意识到它可以处理关系的 Django 搜索真正的亮点。因此,假设我们希望它在图片“的标题,作者姓名和注释”文本进行搜索。我们如何做到这一点?
class PictureAdmin(admin.ModelAdmin):
search_fields = ('title', 'author__name', 'comments__text', )
如果你的数据库是够大,不要忘记添加一些全文索引来增加搜索速度。
Tip #5: “在站点查看”的简单实现
在站点查看一个对象的界面是非常普及的需求,默认情况下,你必须打开该对象的表单,然后点击按钮“在站点查看”。以下代码展示如何使此过程更容易一些:
class PictureAdmin(admin.ModelAdmin):
list_fields = [..., 'object_link']
def object_link(self, item):
url = item.get_absolute_url()
return u'open'.format(url=url)
object_link.short_description = 'View on site'
object_link.allow_tags = True
这段代码给列表中每个对象都添加了“在站点查看”的链接。在此,我们假定你的模型(Model)已经实现了get_absolute_url()方法。如果还没有 – 那现在就去实现 ,这将为你节省很多时间。你也可能会想将这个片段转移到一个 mixin,或公用的 admin 基类。
Tip #6: 在列表页就地编辑字段
假设我们需要给评论加一个编辑的备注。很自然,我们希望不需要对每条评论都去打开评论的changeform。要做到这点,我们可以稍微修改一下ModelAdmin:
class CommentAdmin(admin.ModelAdmin):
list_display_fields = ('picture', 'author', 'editors_note', )
list_editable = ('editors_note', )
这样就搞定了,现在打开评论列表,可以按照需要进行过滤,还可以在评论上即时添加备注。
Tip #7: 根据需要自定义 total 字段
每个 changelist 最下方都有一行列出总数(total)。假设我们需要把猫和狗的图片数量区分开来。这个功能需要的代码稍微多一些:我们需要重载 changelist 和 html 模板(更多内容参考模板重载)。
from django.contrib.admin.views.main import ChangeList
class PicturesChangeList(admin.ChangeList):
def get_results(self, request):
super(PicturesChangeList, self).get_results(request)
totals = self.result_list.aggregate(
dogs_count=Sum(Case(When(animal_kind=Picture.DOG, then=1),
output_field=IntegerField())),
cats_count=Sum(Case(When(animal_kind=Picture.CAT, then=1),
output_field=IntegerField())))
self.totals = totals
class PictureAdmin(admin.ModelAdmin):
def get_changelist(self, request):
return PicturesChangeList
模板的内容:
{% extends 'admin/change_list.html' %}
{% block result_list %}
{{ block.super }}
<p>
There are
<strong>
{{ cl.totals.dogs_count|default:'none' }} dogs and
{{ cl.totals.cats_count|default:'none' }} cats
strong>
on this page.
p>
{% endblock %}
Tip #8: 对某些用户只读的 admin 界面
啥意思?假设你的祖母打算瞅一眼这些可爱的图片,她站在你背后,觉得 Django 的 admin 界面挺有意思。不过你能肯定,她要是使用 admin 界面,恐怕一个按钮的点击就能毁掉整个网站。那么,我们加上 grandma-proof™,这样就支持只读的 admin 界面(就是某人说的“数据浏览”):
class GrandmaProofAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
if request.user.username == 'granny':
return [f.name for f in self.model._meta.fields]
else:
return super(GrandmaProofAdmin, self).get_readonly_fields(request, obj)
class PictureAdmin(GrandmaProofAdmin):
...
现在你可以安全的把修改图片的权限放开给你的祖母,这样她就能浏览图片列表。要注意这个方案肯定不能适用于所有使用场景,你还需要处理更多的情况。
Tip #9: 为每个对象自定义 action
有时候你需要在单个对象上执行特定的 action。‘actions’工具当然可以完成这个任务,不过过程会显得很麻烦:点击对象、选择 action、再点击一个按钮……肯定有更便捷的方式,对吧?让我们想办法只点击一次就全部搞定。
这次我们要实现老祖母的另一个宏达的想法。她希望能给某些编辑发 email,告诉他们她喜欢的所有图片。
class PictureAdmin(admin.ModelAdmin):
list_fields = (..., 'mail_link', )
def mail_link(self, obj):
dest = reverse('admin:myapp_pictures_mail_author',
kwargs={'pk': obj.pk})
return '{title}'.format(url=dest, title='send mail')
mail_link.short_description = 'Show some love'
mail_link.allow_tags = True
def get_urls(self):
urls = [
url('^(?P\d+)/sendaletter/?$',
self.admin_site.admin_view(self.mail_view),
name='myapp_pictures_mail_author'),
]
return urls + super(PictureAdmin, self).get_urls()
def mail_view(self, request, *args, **kwargs):
obj = get_object_or_404(Picture, pk=kwargs['pk'])
send_mail('Feel the granny\'s love', 'Hey, she loves your pet!',
'granny@yoursite.com', [obj.author.email])
self.message_user(request, 'The letter is on its way')
return redirect(reverse('admin:myapp_picture_changelist'))
但愿她现在能够满意。现在每个对象字段加上了一个链接,让她点一下就可以发送邮件。
Bonus Tip: 只需为 admin 添加一行代码来减少查询量
Django admin (Django 也是如此) 最常用也是最有用的技巧是 select_related。呃,你已经都知道了?不就是把对象的名字传给 ModelAdmin 的 list_select_related 属性来实现相关对象的预加载嘛。但是,你知道你并没有描述全部的相关对象吗?只需要设置成 True,Django 就可以自动预加载外部对象:
class PictureAdmin(admin.ModelAdmin):
list_select_related = True
Django admin 的 9 个技巧的更多相关文章
- Django admin美化插件suit应用[原创]
前言 由于比较懒,自己弄了一个用户验证,没有自己写后台,用了django自带的user认证,并通过admin直接进行管理,但默认的admin并不漂亮,于是使用了这个django-suit插件,效果对比 ...
- Django admin 权威指南(一)
版本: Django 1.10 此部分由官方文档<6.5.1 The Django admin site>翻译而来. 6.5.1.1 概览 默认情况下,使用startproject的时候, ...
- Django Admin 简单部署上线
前言 打算为公司弄一个管理公用密码的平台,由于比较懒,就选择使用Django admin,默认的admin并不漂亮,于是我使用了这个django-suit插件来美化 如图: 是不是比原来的漂亮多了. ...
- 你应该使用 Django admin 的 9 个理由(转)
你应该使用 Django admin 的 9 个理由 “问题是,我问到的每个人都持反对意见,他们认为 admin 只限于超级用户,很不灵活并且是难以定制.”—来自 Reddit 的 andybak 我 ...
- Django admin 显示图片
我有一个表用来储存轮播图片,有一个 `picture` 字段储存的是图片的url,图片的 url 通过上传文件到 cdn 获得.目前这个表的编辑是通过自定义一个 `ModelForm`,然后重写 Dj ...
- [系统开发] Django Admin上传图片简单校验
我的 models里有个ImageField字段,用来保存用户头像,希望通过Django Admin上传时校验头像大小,如果太大就报错,并且不保存. 网上有不少方法,有的通过第三方软件实现,有的通过自 ...
- SQLAlchemy连接数据库并在django admin显示
SQLAlchemy 0.7 postgersql 9.0 SQLAlchemy连接数据库有两种方法,一种是classic,一种是modern 1,modern方法 from sqlalch ...
- Django admin site(一)ModelAdmin Options
Admin管理界面是django的杀手级应用.它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即向网站中添加内容. 要使用admin,可以按照下面的步骤: 将'dj ...
- Django admin究竟要怎么写才优雅
比如在Django admin 注册models时,会用到. 对于APP里自带的models,可以使用这种方式注册. from django.contrib import admin # Regist ...
随机推荐
- async -- await 解决数据异步获取
在React组件中,也比较一下 Promise 和 Async/Await 的方法异同. 传统地使用 Promise : import React, { Component } from 'react ...
- js 终止 for 循环
1.break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句. 2.for循环如果是多层循环 可以将循环命名,跳出指定的循环. first://需要将循环命名 for(var ...
- XML Schema学习札记(1)——基础总览
内容整理自:www.w3school.com.cn 转载自:http://www.xgezhang.com/xml_schema_1.html 什么是XML Schema? XML Schema 是基 ...
- POJ 1163&& 3176 The Triangle(DP)
The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 41169 Accepted: 24882 De ...
- H5 Canvas | 画布中变量作用域与setInterval方法同步执行探究
Demo - 随机绘制圆环 实现思路: 将一个圆环的绘制分成100份,setInterval()方法定义每隔时间n绘制一段新的,每份的开始路径都是上一次的结束路径,实现步进绘制. 通过Math.ran ...
- Java的IO操作,个人理解。
先看一段代码: import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import ...
- CXF 调用方式——动态创建客户端(调用稳定版本号为2.7.18)
今天用动态创建客户端的方式调用webservice,报了这样一个错: 2017-01-05 20:51:46,029 DEBUG main org.apache.cxf.common.logging. ...
- ML:交叉验证Cross-Validation
PRML中首章绪论的模型选择,提到两个方法: 1.交叉验证(Cross-Validation) 2.赤池信息准则(Akaike Information Criterion),简称:AIC. 交叉验证是 ...
- linux 常用的命令(转)
常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir ...
- 转在Python中实现PageFactory模式
转自: http://www.cnblogs.com/fnng/p/5092383.html 关于 PageFactory 的概念主要是Java中内置了PageFactory类. import org ...