Django 強大的admin模塊

django的後臺我們只要加少些代碼,就可以實現強大的功能。

與後臺相關文件:每個app中的 admin.py 文件與後臺相關。


下面示例是做一個後臺添加博客文章的例子:

一,新建一個 名稱爲 zqxt_admin 的項目

1
django-admin.py startproject zqxt_admin

二,新建一個 叫做 blog 的app

1
2
3
4
5
# 進入 zqxt_admin 文件夾
cd zqxt_admin
 
# 創建 blog 這個 app
python manage.py startapp blog

注意:不同版本的 Django 創建 project 和 app 出來的文件會有一些不同

三,修改 blog 文件夾中的 models.py

1
2
3
4
5
6
7
8
9
10
# coding:utf-8
from django.db import models
 
 
class Article(models.Model):
    title = models.CharField(u'標題', max_length=256)
    content = models.TextField(u'內容')
 
    pub_date = models.DateTimeField(u'發表時間', auto_now_add=True, editable = True)
    update_time = models.DateTimeField(u'更新時間',auto_now=True, null=True)

四,把 blog 加入到settings.py中的INSTALLED_APPS中

1
2
3
4
5
6
7
8
9
10
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 
    'blog',
)

提示:INSTALLED_APPS 是一個元組,每次加入新的app的時候,在後面都加一個逗號,這是一個好習慣。

五,同步所有的數據表

1
2
3
4
5
6
# 進入包含有 manage.py 的文件夾
python manage.py makemigrations
python manage.py migrate
 
注意:Django 1.6.x 及以下的版本需要用以下命令
python manage.py syncdb

可以看到:

Creating tables ...

Creating table django_admin_log

Creating table auth_permission

Creating table auth_group_permissions

Creating table auth_group

Creating table auth_user_groups

Creating table auth_user_user_permissions

Creating table auth_user

Creating table django_content_type

Creating table django_session

Creating table blog_article


You just installed Django's auth system, which means you don't have any superusers defined.

Would you like to create one now? (yes/no): yes

Username (leave blank to use 'tu'): tu

Email address: 

Password: 

Password (again): 

Superuser created successfully.

Installing custom SQL ...

Installing indexes ...

Installed 0 object(s) from 0 fixture(s)

如果是 Django 不主動提示創建管理員(Django 1.9不提示)用下面的命令創建一個帳號

1
python manage.py createsuperuser

六,修改 admin.py 

進入 blog 文件夾,修改 admin.py 文件(如果沒有新建一個),內容如下

1
2
3
4
5
from django.contrib import admin
from .models import Article
 
 
admin.site.register(Article)

只需要這三行代碼,我們就可以擁有一個強大的後臺!

提示:urls.py中關於 admin的已經默認開啓,如果沒有,參考這裏

七,打開 開發服務器

1
2
python manage.py runserver
# 如果提示 8000 端口已經被佔用,可以用 python manage.py runserver 8001 以此類推

訪問 http://localhost:8000/admin/ 輸入設定的帳號和密碼, 就可以看到:

點擊 Articles,動手輸入 添加幾篇文章,就可以看到:

我們會發現所有的文章都是叫 Article object,這樣肯定不好,比如我們要修改,如何知道要修改哪個呢?

我們修改一下 blog 中的models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
# coding:utf-8
from django.db import models
 
 
class Article(models.Model):
    title = models.CharField(u'標題', max_length=256)
    content = models.TextField(u'內容')
 
    pub_date = models.DateTimeField(u'發表時間', auto_now_add=True, editable = True)
    update_time = models.DateTimeField(u'更新時間',auto_now=True, null=True)
 
    def __unicode__(self):# 在Python3中用 __str__ 代替 __unicode__
        return self.title

我們加了一個 __unicode__ 函數,刷新後臺網頁,會看到:

所以推薦定義 Model 的時候 寫一個 __unicode__ 函數(或 __str__函數)

技能提升:如何兼容python2.x和python3.x呢?

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# coding:utf-8
from __future__ import unicode_literals
 
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
 
@python_2_unicode_compatible
class Article(models.Model):
    title = models.CharField('標題', max_length=256)
    content = models.TextField('內容')
 
    pub_date = models.DateTimeField('發表時間', auto_now_add=True, editable = True)
    update_time = models.DateTimeField('更新時間',auto_now=True, null=True)
 
    def __str__(self):
        return self.title

python_2_unicode_compatible 會自動做一些處理去適應python不同的版本,本例中的 unicode_literals 可以讓python2.x 也像 python3 那個處理 unicode 字符,以便有更好地兼容性。

八,在列表顯示與字段相關的其它內容

後臺已經基本上做出來了,可是如果我們還需要顯示一些其它的fields,如何做呢?

1
2
3
4
5
6
7
from django.contrib import admin
from .models import Article
 
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title','pub_date','update_time',)
 
admin.site.register(Article,ArticleAdmin)

list_display 就是來配置要顯示的字段的,當然也可以顯示非字段內容,或者字段相關的內容,比如:

1
2
3
4
5
6
7
8
9
class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
 
    def my_property(self):
        return self.first_name + ' ' + self.last_name
    my_property.short_description = "Full name of the person"
 
    full_name = property(my_property)

在admin.py中

1
2
3
4
5
6
7
8
9
10
11
12
13
from django.contrib import admin
from .models import Article, Person
 
 
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title''pub_date''update_time',)
 
 
class PersonAdmin(admin.ModelAdmin):
    list_display = ('full_name',)
 
admin.site.register(Article, ArticleAdmin)
admin.site.register(Person, PersonAdmin)


到這裏我們發現我們又有新的需求,比如要改 models.py 中的字段,添加一個文章的狀態(草稿,正式發佈),這時候我們就需要更改表,django 1.7以前的都不會自動更改表,我們需要用第三方插件 South,參見 Django 遷移數據

Django 1.7 及以上用以下命令來同步數據庫表的更改

1
2
python manage.py makemigrations
python manage.py migrate

本節代碼下載:

zqxt_admin (Django 1.6).zip (基於Django 1.6,後臺帳號 tu 密碼 zqxt)

zqxt_admin (Django 1.9).zip (基於 Django 1.9 後臺帳號 tu 密碼 ziqiangxuetang)


其它一些常用的功能:

搜索功能:search_fields = ('title', 'content',) 這樣就可以按照 標題或內容搜索了

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields


篩選功能:list_filter = ('status',) 這樣就可以根據文章的狀態去篩選,比如找出是草稿的文章

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter


新增或修改時的佈局順序https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets


有時候我們需要對django admin site進行修改以滿足自己的需求,那麼我們可以從哪些地方入手呢?

以下舉例說明:

1.定製加載的列表, 根據不同的人顯示不同的內容列表,比如輸入員只能看見自己輸入的,審覈員能看到所有的草稿,這時候就需要重寫get_queryset方法

1
2
3
4
5
6
7
class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super(MyModelAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs
        else:
            return qs.filter(author=request.user)

該類實現的功能是如果是超級管理員就列出所有的,如果不是,就僅列出訪問者自己相關的


2.定製搜索功能(django 1.6及以上纔有)

1
2
3
4
5
6
7
8
9
10
11
12
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)
            queryset |= self.model.objects.filter(age=search_term_as_int)
        except:
            pass
        return queryset, use_distinct

queryset 是默認的結果,search_term 是在後臺搜索的關鍵詞

3.修改保存時的一些操作,可以檢查用戶,保存的內容等,比如保存時加上添加人

1
2
3
4
5
6
from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.user = request.user
        obj.save()

其中obj是修改後的對象,form是返回的表單(修改後的),當新建一個對象時 change = False, 當修改一個對象時 change = True
如果需要獲取修改前的對象的內容可以用

1
2
3
4
5
6
7
from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj_original = self.model.objects.get(pk=obj.pk)
        obj.user = request.user
        obj.save()

那麼又有問題了,這裏如果原來的obj不存在,也就是如果我們是新建的一個怎麼辦呢,這時候可以用try,except的方法嘗試獲取,當然更好的方法是判斷一下這個對象是新建還是修改,是新建就沒有 obj_original,是修改就有

1
2
3
4
5
6
7
8
9
10
11
from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if change:# 更改的時候
            obj_original = self.model.objects.get(pk=obj.pk)
        else:# 新增的時候
            obj_original = None
 
        obj.user = request.user
        obj.save()

4, 刪除時做一些處理,

1
2
3
4
5
6
7
8
9
from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def delete_model(self, request, obj):
        """
        Given a model instance delete it from the database.
        """
        # handle something here
        obj.delete()
以上內容來自Django自強學堂
發佈了16 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章