django的后台我们只要少写些代码,就可以实现强大的功能,与后台相关文件:每个app中的admin.py文件与后台相关
下面实例是做一个后台添加博客文章的例子:
####### 1、新建一个名称为learn_admin的项目
django-admin.py startproject learn_admin
2、新建一个叫做blog的app
# 进入 learn_admin这个文件夹
cd learn_admin/
# 创建blog这个app
python manage.py startapp blog
# 注意不同版本的Django创建project和app出来的文件会有一些不同
3、修改blog文件中的models.py
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=256, '标题')
content = models.TextField('内容')
pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
updatetime= models.DateTimeField('更新时间', auto_now=True, null=True)
# 前三个modelField,DateTimeField和DateField和TimeField存储的内容分别对应着datetime(),date(),time()三个对象。
# 对于auto_now=False和auto_now_add=False两者默认值都为False。
# auto_now=Ture,字段保存时会自动保存当前时间,但要注意每次对其实例执行save()的时候都会将当前时间保存,也就是不能再手动给它存非当前时间的值。
# auto_now_add=True,字段在实例第一次保存的时候会保存当前时间,不管你在这里是否对其赋值。但是之后的save()是可以手动赋值的。也就是新实例化一个model,想手动存其他时间,就需要对该实例save()之后赋值然后再save()。
4、把blog加入到settings.py中的 INSTALLED_APPS中
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
# 提示:INSTALLED_APPS是一个列表,每次加入新的app的时候,在后面都加一个逗号,这是一个好习惯
5、同步所有的数据表
# 进入包含有 manage.py的文件夹
python manage.py makemigrations
python manage.py migrate
# 注意:Django 1.6.x及以下的版本需要以下命令
python manage.py syncdb
# 如果是Django 不主动提示创建管理员(Django 1.9不提示),用下面的命令创建一个账号
python manage.py createsuperuser
# 创建用户名,不写默认taytay
Username (leave blank to use 'taytay'): learn_user
Email address: 123@163.com
Password:
Password (again):
Superuser created successfully.
修改 admin.py
进入blog文件夹,修改admin.py(如果没有新建一个),内容如下:
from django.contrib import admin
# Register your models here.
from .models import Article
admin.site.register(Article)
# 只需要这三行代码,我们就可以拥有一个强大的后台
提示:urls.py中关于admin的已经默认开启,如果没有,参考这里
7、打开开发服务器
python manage.py runserver
# 如果提示 8000端口已经被占用,可以用python manage.py runserver 8001 以此类推
Performing system checks...
System check identified no issues (0 silenced).
October 26, 2017 - 03:28:38
Django version 1.11, using settings 'learn_admin.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C
访问 http://127.0.0.1:8000/admin/login/?next=/admin/ 然后输入设定的账号和密码,就可以看到
点击Articles,动手输入添加几篇文章,就可以看到:
我们会发现所有的文章都是叫 Article object,这样肯定不好,比如我们要修改,如何知道修改那个呢?
我们修改一下blod中的model.py
class Article(models.Model):
title = models.CharField('标题', max_length=256)
content = models.TextField('内容')
pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
updatetime= models.DateTimeField('更新时间', auto_now=True, null=True)
def __str__(self):
return self.title
# 在python2中用__unicode__:代替__str__
我们加入一个str函数,刷新网页,会看到:
所以推荐定义Model的时候写一个str函数(或unicode函数)
提升技能,如何兼容python2.x和python3.x呢?
示例如下:
from __future__ import unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
# Create your models here.
@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)
updatetime= models.DateTimeField('更新时间', auto_now=True, null=True)
def __str__(self):
return self.title
python_2_unicode_compatible会自动做一些处理去适应python不同的版本,本例中的unicode_literals可以让python2.x也像python3那样处理Unicode字符,以便更好的兼容
8、在列表显示字段相关其他内容
后台基本已经做出来了,可是如果我们还需要显示一些其他的fields,如何做呢?
from django.contrib import admin
# Register your models here.
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date', 'update_time',)
admin.site.register(Article, ArticleAdmin)
list_display就是来配置要现实的字段,当然也可以显示非字段内容,或者字段相关的内容,比如:
class People(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
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中:
from django.contrib import admin
# Register your models here.
from .models import *
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date', 'update_time',)
admin.site.register(Article, ArticleAdmin)
class PeopleAdmin(admin.ModelAdmin):
list_display = ('full_name')
admin.site.register(People , PeopleAdmin)
到这里我们发现又有新的需求,比如要改models.py中的字段,添加一个文章的状态(草稿,正式发布),这时候我们就需要更改表,django1.7以前的都不会自动更改表,我们需要第三方插件South
Django 1.7及以上 用一下命令同步数据库表的更改
python manage.py makemigrations
python manage.py migrate
有时候我们需要对Django admin site 进行修改以满足自己的需求,那么我们可以从哪些地方入手呢?
以下举例说明:
1、定制加载的列表,根据不同的人显示不同的内容列表,比如输入员只能看见自己输入的,审核员能看到所有的草稿,这时候就需要重写get_queryset方法
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以上才有)
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.修改保存时的一些操作,可以检查用户,保存的内容等,比如保存时加上添加人
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
如果需要获取修改前的对象的内容可以用
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,是修改就有
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, 删除时做一些处理,
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()
网友评论