1. 程式人生 > >Django admin的一些有用定製

Django admin的一些有用定製

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, req

相關推薦

Django admin一些有用定製

Model例項,myapp/models.py: from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = mod

python--django一些有用的工具引入路徑

django.shortcuts render:渲染前端頁面 redirect:跳轉到其他頁面 django forms:表單驗證 # 定義 class Form(forms.Form): name = forms.CharField(error_messages={'requi

django admin有用的自定義功能

轉載 ngx 博客園 title bsp div body nbsp 有用 引用園友 無名小妖 的博客 https://www.cnblogs.com/wumingxiaoyao/p/6928297.html 寫的很好,但是博客園不能轉載,不過我已經點贊了~django a

一些有用的Python指令

交互模式 import col 命令 輸入 當前 模式 nbsp code 修改IDLE工作路徑,在命令交互模式下輸入如下指令: >>> import os >>> os.getcwd() #查看當前的工作路徑 >>>

Django Admin site 顯示問題

site ngs 問題 增加 拷貝 class 顯示 開源 ase Django Admin site 顯示問題 今天配置了一下Django admin site,可是admin site的顯示有一些問題,當我打開源碼。訪問裏面的admin 的css

一些有用的容易忘記的函數總結。

系統常量 config function and 現在 line res 字符串 cnblogs 一、PHP 提供非常有用的系統常量 可以讓你得到當前的行號 (__LINE__),文件 (__FILE__),目錄 (__DIR__),函數名 (__FUNCTION__),類

關於django一些回顧(主要是對數據庫的操作)

周期 聯合 gte tin diango hunk edi quest 傳輸 1.diango請求的生命周期 url->路由系統-->視圖函數(獲取模版+數據) 渲染 -->字符串返回給用戶2.路由系統 /index/ ---> 函數或者類

django admin中文輸入編碼錯誤

描述 self. mode div self 中文 ret str min 修改models裏面的str方法,改為unicode class Category(models.Model): name = models.CharField(max_length

django admin

pri 點擊 路由 site print arch reg key mode 1,ADMIN 操作 註冊 amdin.py from django.contrib import adminfrom app01 import modelsadmin.site.registe

django admin富文本編輯kindeditor

瀏覽器 fig lan 代碼 model mod eat reg 文本編輯器 最近在做django項目,需要在後臺管理系統加入富文本編輯 其實加入富文本編輯很簡單,就是導入幾個編輯器的js腳本到admin頁面內,下面說說怎麽做 第一步,下載想要的富文本編輯器如kinde

如何解決django-admin.py startproject mysite在window下無法創建文件

django-admin.pydjango-admin.py startproject mysite 在window上無論我怎麽試,都沒法創建,總是跳出一個#!c:\python27\python.exe from django.core import management if __name__ == "

一些有用的位運算操作

操作 src 運算操作 bsp log img .com mage 9.png 一些有用的位運算操作

自己關於Django一些實踐

表示 pass djang erl res rect() 代碼 user index 一 render() redirect() HttpResponse() 響應 是個什麽東西 def login(request): if request.method==

iptables 一些有用的規則

connlimit dos ron mysq -h 12個 特殊 flag style -A INPUT -i lo -j ACCEPT #允許本機內部訪問,即回環 -A INPUT -m state --state RELATED,ESTABLISHED -j AC

[2018-01-13] 安裝Django一些筆記

djang 下載 結構 ins 1-1 項目 sta setup manage 安裝django   pip install Django = =1.10.2   下載源碼,進入根目錄執行 python setup.py install 確認是否已經安裝成功 pytho

Django一些request封裝的常用功能

color ref 設置 用戶密碼 clas ati 擴展 tle span 一些常用的request對象屬性 request.scheme:代表請求的方案,http或者https request.path:請求的路徑,比如請求127.0.0.1/org/list,那這

django-admin

site arm ngx ucc project jet pos har app 配置 在項目的app中有admin.py文件 在此文件中導入我們寫好的models並配置 from django.contrib import admin # Register y

Django 【第二十五篇】Django admin源碼解析

第一個元素 div 再次 register d+ __init__ () views quest 一、admin的源碼流程 首先可以確定的是:路由關系一定對應一個視圖函數 a、當點擊運行的時候,會先找到每一個app中的admin.py文件,並執行 b、執行urls.py

Django admin 設置和定制

filter unicode mod desc mef nbsp cls rfi 繼承 models 在 models.py 中定義,每個 model 是一個 class: from django.db import models class Performance

Django-admin管理工具

排序規則 request 中文 設計模式 book filters ron template 數據排序 Django 提供了基於 web 的管理工具。 Django 自動管理工具是 django.contrib 的一部分。你可以在項目的 settings.py 中的 I