Model实例,myapp/models.py:

from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() # On Python 3: def __str__(self):
def __unicode__(self):
return self.name class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField() # On Python 3: def __str__(self):
def __unicode__(self):
return self.name class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField() # On Python 3: def __str__(self):
def __unicode__(self):
return self.headline

类级别权限

默认情况下,superuser可以访问admin界面的所有Model,但有时候只想让一些用户只能访问一些特定的Model。

可以定制自己的User对象的has_perm()方法:

class MyUser(AbstractBaseUser):
...
def has_perm(self, perm, obj=None):
if self.is_superuser:
return True
elif self.can_edit:
if perm=='myapp.add_entry':
return True
else:
return False
else:
return False

这样superuser具有全部权限。普通user的can_edit属性为True时,就具有了创建Entry实例的权限,其余用户无权限。

也可以定制ModelAdmin的has_add_permission(),has_change_permission(),has_delete_permission()方法:

    def has_add_permission(self, request):
"""
Returns True if the given request has permission to add an object.
Can be overridden by the user in subclasses.
"""
opts = self.opts
codename = get_permission_codename('add', opts)
if request.user.can_edit:
return True
else:
return request.user.has_perm("%s.%s" % (opts.app_label, codename))

字段级别的权限

不同权限的可以编辑不同的内容,可以通过get_readonly_fileds()来添加字段只读权限。

class EntryAdmin(admin.ModelAdmin):
list_display=(...)
search_fields=(...)
def get_readonly_fields(self,request,obj=None):
if not request.user.is_superuser and not request.user.can_edit:
return [f.name for f in self.model._meta.fields]
return self.readonly_fields

重写Model的save行为

可以直接重写model的save()方法:

from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() def save(self, *args, **kwargs):
do_something()
super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
do_something_else()

阻止save():

from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() def save(self, *args, **kwargs):
if self.name == "Yoko Ono's blog":
return # Yoko shall never have her own blog!
else:
super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.

也可以重写ModelAdmin的save_model()方法,根据不同的用户定制不同的save行为:

from django.contrib import admin

class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()

其中obj是修改后的对象,当新建一个对象时 change = False, 当修改一个对象时 change = True,可以获得修改前的对象:

from django.contrib import admin
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if change:
obj_old = self.model.objects.get(pk=obj.pk)
else:
obj_old = None
obj.user = request.user
obj.save()

不同的用户显示不同的数据行,重写列表页面返回的查询集

ModelAdmin提供了一个钩子程序 —— 它有一个名为queryset() 的方法,该方法可以确定任何列表页面返回的默认查询集。

class MyModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(MyModelAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)

定制过滤器list_filter

从django.contrib.admin.SimpleListFilter继承一个子类,提供title和parameter_name属性,并重写 lookups和queryset方法。

from datetime import date

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _ class DecadeBornListFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = _('decade born') # Parameter for the filter that will be used in the URL query.
parameter_name = 'decade' def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return (
('80s', _('in the eighties')),
('90s', _('in the nineties')),
) def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
# Compare the requested value (either '80s' or '90s')
# to decide how to filter the queryset.
if self.value() == '80s':
return queryset.filter(birthday__gte=date(1980, 1, 1),
birthday__lte=date(1989, 12, 31))
if self.value() == '90s':
return queryset.filter(birthday__gte=date(1990, 1, 1),
birthday__lte=date(1999, 12, 31)) class PersonAdmin(admin.ModelAdmin):
list_filter = (DecadeBornListFilter,)

parameter_name和title是必须的。look_up方法返回出现在列表页右侧过滤器中的选项和描述。parameter_name为附加在url后面get请求的参数名,self.value()返回该参数对应的值。

根据不同的用户定制:

class AuthDecadeBornListFilter(DecadeBornListFilter):

    def lookups(self, request, model_admin):
if request.user.is_superuser:
return super(AuthDecadeBornListFilter,
self).lookups(request, model_admin) def queryset(self, request, queryset):
if request.user.is_superuser:
return super(AuthDecadeBornListFilter,
self).queryset(request, queryset)

model_admin为ModelAdmin实例:

class AdvancedDecadeBornListFilter(DecadeBornListFilter):

    def lookups(self, request, model_admin):
"""
Only show the lookups if there actually is
anyone born in the corresponding decades.
"""
qs = model_admin.get_queryset(request)
if qs.filter(birthday__gte=date(1980, 1, 1),
birthday__lte=date(1989, 12, 31)).exists():
yield ('80s', _('in the eighties'))
if qs.filter(birthday__gte=date(1990, 1, 1),
birthday__lte=date(1999, 12, 31)).exists():
yield ('90s', _('in the nineties'))

定制搜索功能

class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'age')
search_fields = ('name',) def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= self.model.objects.filter(age=search_term_as_int)
return queryset, use_distinct

queryset是查询集,search_term是搜索词。

外键字段过滤

在添加对象时显示外键选项时,太多的选项不太友好,这时候需要过滤出符合要求的对象供选择。

class MyModelAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "car":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

  

Django admin的一些有用定制的更多相关文章

  1. 06: Django Admin

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  2. DJANGO ADMIN 一些有用的设置(转)

    DJANGO ADMIN 一些有用的设置   Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据.后台管理可以在各个app的admin.py文件中进行控制.以下是我最近摸 ...

  3. Django admin定制化,User字段扩展[原创]

    前言 参考上篇博文,我们利用了OneToOneField的方式使用了django自带的user,http://www.cnblogs.com/caseast/p/5909248.html , 但这么用 ...

  4. Django从Models 10分钟定制一个Admin后台

    目录 Django从Models 10分钟建立一套RestfulApi Django从Models 10分钟定制一个Admin后台 简介 Django自带一个Admin后台, 支持用户创建,权限配置和 ...

  5. 定制django admin页面的跳转

    在django admin的 change_view,  add_view和delete_view页面,如果想让页面完成操作后跳转到我们想去的url,该怎么做 默认django admin会跳转到ch ...

  6. django admin 设置(转载https://www.cnblogs.com/wumingxiaoyao/p/6928297.html)

    Django admin 一些有用的设置   Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据.后台管理可以在各个app的admin.py文件中进行控制.以下是我最近摸 ...

  7. django admin 使用

    Django admin 中一些常用的设置 Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据.后台管理可以在各个app的admin.py文件中进行控制.以下是我最近摸索 ...

  8. 利用 Django admin 完成更多任务(转)

    利用 Django admin 完成更多任务   Django admin Django 为未来的开发人员提供了许多功能:一个成熟的标准库,一个活跃的用户社区,以及 Python 语言的所有好处.虽然 ...

  9. 你应该使用 Django admin 的 9 个理由(转)

    你应该使用 Django admin 的 9 个理由 “问题是,我问到的每个人都持反对意见,他们认为 admin 只限于超级用户,很不灵活并且是难以定制.”—来自 Reddit 的 andybak 我 ...

随机推荐

  1. 3. opencv进行SIFT特征提取

    opencv中sift特征提取的步骤 使用SiftFeatureDetector的detect方法检测特征存入一个向量里,并使用drawKeypoints在图中标识出来 SiftDescriptorE ...

  2. Java 网络编程(转)

    一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...

  3. unity项目实现“再按一次退出程序”提示功能

    unity项目,再按一次退出程序,按第一次做提示,再按一次,程序退出. float _waitTime = 2f;//前后两次按退出间隔时间 void OnGUI() { ) { GUI.Label( ...

  4. 常用汉字的Unicode码表

    \u96d5\u864e\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u77 ...

  5. 【笔记】UML核心元素

    1.参与者 定义:在系统之外与系统交互的某人或某物. 特点:1.可以非人:2.与系统直接交互:3.主动发出动作并获得反馈:4.涉众(stakerholder)的代表 具有两个版型: 1.业务主角(bu ...

  6. tomcat内存溢出,设置

    tomcat/bin/catalina.bat里找到echo Using CATALINA_BASE:   "%CATALINA_BASE%" ,在上方设置:    set JAV ...

  7. Maven--(一个坑)在settings.xml文件中添加mirrors导致无法新建Maven项目

    这是用新电脑第一次创建Maven项目--当然是一个测试项目.已经差不多忘了该怎样做,所以参考我的博客:http://www.cnblogs.com/wql025/p/4996486.html,这应该是 ...

  8. DevExpress控件使用系列--ASPxUploadControl(图片上传及预览)

        1.控件功能     列表控件展示数据.弹框控件执行编辑操作.Tab控件实现多标签编辑操官方说明 2.官方示例       2.1 ASPxImage                http: ...

  9. 【BZOJ】【1086】 【SCOI2005】王室联邦

    树分块 orz vfk && PoPoQQQ http://vfleaking.blog.163.com/blog/static/174807634201231684436977/ h ...

  10. PAT-乙级-1051. 复数乘法 (15)

    1051. 复数乘法 (15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 复数可以写成(A + Bi)的常规 ...