对于某一类网站, 管理界面 是基础设施中非常重要的一部分。 这是以网页和有限的可信任管理者为基础的界面,它可以让你添加,编辑和删除网站内容。 一些常见的例子: 你可以用这个界面发布博客,后台的网站管理者用它来润色读者提交的内容,你的客户用你给他们建立的界面工具更新新闻并发布在网站上,这些都是使用管理界面的例子。
找不到那个说后台界面没有css的在哪一块了,丢这里吧 单纯的编码问题 import sys reload(sys) sys.setdefaultencoding('gbk') 扔到配置文件setting.py里解决了 via.http://tieba.baidu.com/p/2692296390 #9楼 下面的方法我试过,反正没效果 ----------------------------------------------------- 我是ls的 lsss说的文章 http://blog.csdn.net/monkeyduck/article/details/19826421 文章引用的文章 http://blog.webforefront.com/archives/2011/02/python_ascii_co.html 我照着改了个gbk,but,改完过后那个自带的服务器都启动不了了,改回来才有正常了,不知道有人遇到一样的问题不
但是管理界面有一问题: 创建它太繁琐。 当你开发对公众的功能时,网页开发是有趣的,但是创建管理界面通常是千篇一律的。 你必须认证用户,显示并管理表格,验证输入的有效性诸如此类。 这很繁琐而且是重复劳动。
Django 在对这些繁琐和重复的工作进行了哪些改进? 它用不能再少的代码为你做了所有的一切。 Django 中创建管理界面已经不是问题。
这一章是关于 Django 的自动管理界面。 这个特性是这样起作用的: 它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即工作。
请注意我们建议你读这章,即使你不打算用admin。因为我们将介绍一些概念,这些概念可以应用到Django的所有方面,而不仅仅是admin
django.contrib 包
Django自动管理工具是django.contrib的一部分。django.contrib是一套庞大的功能集,它是Django基本代码的组成部分,Django框架就是由众多包含附加组件(add-on)的基本代码构成的。 你可以把django.contrib看作是可选的Python标准库或普遍模式的实际实现。 它们与Django捆绑在一起,这样你在开发中就不用“重复发明轮子”了。
管理工具是本书讲述django.contrib的第一个部分。从技术层面上讲,它被称作django.contrib.admin。django.contrib中其它可用的特性,如用户鉴别系统(django.contrib.auth)、支持匿名会话(django.contrib.sessioins)以及用户评注系统(django.contrib.comments)。这些,我们将在第十六章详细讨论。在成为一个Django专家以前,你将会知道更多django.contrib的特性。 目前,你只需要知道Django自带很多优秀的附加组件,它们都存在于django.contrib包里。
激活管理界面
给你们总结一下: 在django1.6中, 你只需要把第五章中在settings.py里注释掉的 INSTALLED_APPS 和 MIDDLEWARE_CLASSES 去掉注释即可。 然后运行python manage.py syncdb 会提示你创建用户 然后运行python manage.py runserver,打开http://127.0.0.1:8000/admin/ 即可看到
Django管理站点完全是可选择的,因为仅仅某些特殊类型的站点才需要这些功能。 这意味着你需要在你的项目中花费几个步骤去激活它。
第一步,对你的settings文件做如下这些改变:
django1.0配置 1.settings.py 添加django.contrib.admin到INSTALLED_APPS INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', ) 2.运行python manage.py syncdb生成管理需要的数据库表结构 3.编辑urls.py,添加urlpatterns from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', …… (r'^admin/(.*)', admin.site.root), ) 4.在需要管理的app下建立admin.py,将需要管理的模块添加 from mysite.books.models import * from django.contrib import admin admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book) **以上类均需添加__unicode__方法 class Publisher(models.Model): …… def __unicode__(self): return self.name 5.运行python manage.py runserver,访问localhost:8000/admin/ 使用刚刚创建的超级用户帐号即可进入管理界面 6.如果之前忘记创建超级用户,可以用python manage.py createsuperuser来创建
这里少了一步,需要在管理的model路径下添加一个admin.py,里面添加 from django.contrib import admin </br> from mysite.books.models import Book, Author, Publisher </br> admin.site.register(Book) </br> admin.site.register(Publisher) </br> admin.site.register(Author) </br>
这里少了一步,需要在管理的model路径下添加一个admin.py,里面添加 from django.contrib import admin from mysite.books.models import Book, Author, Publisher admin.site.register(Book) admin.site.register(Publisher) admin.site.register(Author)
如果你找不到模块的是话,用 from books.models import Book, Author, Publisher ,不用mysit.|我的books的路径是mysit/books,和mysit/mysit同一级。 (我艹~好混乱 啊~)
1.6,这里建议将INSTALLED_APPS,MIDDLEWARE_CLASSES的所有注释都去掉,去掉之后都是6个以django.开头的语句。 我按照英文版去掉了4个注释,后面运行时登录样式不对且报表缺失错误。
- 将
'django.contrib.admin'加入setting的INSTALLED_APPS配置中 (INSTALLED_APPS中的配置顺序是没有关系的, 但是我们喜欢保持一定顺序以方便人来阅读) - 保证
INSTALLED_APPS中包含'django.contrib.auth','django.contrib.contenttypes'和'django.contrib.sessions',Django的管理工具需要这3个包。 (如果你跟随本文制作mysite项目的话,那么请注意我们在第五章的时候把这三项INSTALLED_APPS条目注释了。现在,请把注释取消。) - 确保
MIDDLEWARE_CLASSES包含'django.middleware.common.CommonMiddleware'、'django.contrib.sessions.middleware.SessionMiddleware'和'django.contrib.auth.middleware.AuthenticationMiddleware'。(再次提醒,如果有跟着做mysite的话,请把在第五章做的注释取消。)
用Django 1.3的时候,我把原来的注释的2个包放开,并且下一步的classes也放开后就进不了admin界面,最后按照本文中所写的内容放开就能进去了...
版本:1.6,需要把 INSTALL_APPS中的django.contrib.staticfiles也要取消注释,否则admin的样式消失,加载不了css和js
Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application. 这说明在settings.py文件里面INSTALLED_APPS,django.contrib.admin也要取消注释。
运行 python manage.py syncdb 。这一步将生成管理界面使用的额外数据库表。 当你把'django.contrib.auth'加进INSTALLED_APPS后,第一次运行syncdb命令时, 系统会请你创建一个超级用户。 如果你不这么作,你需要运行python manage.py createsuperuser来另外创建一个admin的用户帐号,否则你将不能登入admin (提醒一句: 只有当INSTALLED_APPS包含'django.contrib.auth'时,python manage.py createsuperuser这个命令才可用.)
这里我运行syncdb时出现了错误,提示No Module named adminmysite.books。很奇怪。不知道怎么产生的。如果我在INTALLED_APPS中注释掉mysite.books就ok了。放开又不行。
创建超级用户时,提示Illegal mix of collection(gbk_chinese_ci, implicit) and (utf8_general_ci,coercible) for operation '='
我执行>manage.py syncdb命令后提示 OperationalError: (2013, "Lost connection to MySQL server at 'waiting for initial communication packet', system error: 0"),好惨 有人知道怎么解决吗?
我的运行一次就输出: Creating tables ... Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s) 这不是代表成功了吗
我执行时直接报错说是语法问题DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s AND `django_content_type`.`app_label` = %s )' at line 1")
恩,是的,当提示Creating tables ... Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s) 就说明成功了,我也是执行的第一次就成功了。 django 1.6.5 需要取消的注释行比以前版本的多,需要 MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) 才可以
django1.8,python3.5,按照如果在命令行输入python manage.py syncdb,到输入email后报出attributeError错误,msvct has no attribute putwch.于是我只好进入shell栏,使用: from django.contrib.auth.models import User user=User.objects.create_superuser('name','emailname@demon.com','password') 创建了超级用户。
syncdb新版本都不用了,现在是makemigrations,migrate,createsuperuser,输入python manage.py help可以看相关命令
需要执行migrate,在执行createsuperuser,否则报.db.utils.OperationalError: no such table: auth_user
需要执行migrate,在执行createsuperuse ls上正解,另外就是密码不得低于8个字符,还有密码和邮箱里面不能有重复,比如你的邮箱是123123@qq.com那么你的密码就不能是abcd123123。
新版本的Django已经不是python manage.py syncdb了改为: 先执行python manage.py makemigrations再执行python manage.py migrate最后执行python manage.py createusperuser
总结,在Python3.X中,创建Django超级用户的流程: 1.进入项目文件夹下运行cmd界面,python manage.py makemigrations 2.python manage.py migrate 3.python manage.py createusperuser 4.正确输入要创建的用户名和密码
第三,将admin访问配置在URLconf(记住,在urls.py中). 默认情况下,命令django-admin.py startproject生成的文件urls.py是将Django admin的路径注释掉的,你所要做的就是取消注释。 请注意,以下内容是必须确保存在的:
ubuntu10.04&python2.6&django1.3.1与所述有所不同。被注释的内容是:#(r'^admin/doc/', include('django.contrib.admindocs.urls')), 执行后也有所不同,内容是documentation.
# Include these import statements...
from django.contrib import admin
admin.autodiscover()
# And include this URLpattern...
urlpatterns = patterns('',
# ...
(r'^admin/', include(admin.site.urls)),
# ...
)
在django 1.2里面 会出现name 'patterns' is not defined的错误 要添加from django.conf.urls.defaults import * 在第一行
读django开发的时候 进入后台管理例子时出现一下错误,原因是 在urls.py文件中没有添加admin 解决办法: 打开urls.py 在前面添加 from django.contrib import admin
忘记在burl.py中添加admin.autodiscover()打开admin网页时会出现错误: You don't have permission to edit anything
urlpatterns = patterns('', (r'^admin/', include(admin.site.urls)), urlpatterns以下,只去上面那一个注释,去多了要报错。
AdminSite' object has no attribute 'urls 楼上的朋友说的对,把urls换成root即可,如下: include(admin,site.root)
如果这块有问题的话,可以把(r'^admin/$',include(admin.site.urls)) 换成(r'^admin/(.*)',admin.site.root),最好复制粘贴,不要手打。 答案来自于:http://stackoverflow.com/questions/946240/difference-between-admin-site-root-and-admin-site-urls
环境是 win10 64 python 2.7.11 django 1.9 使用方法: from django.conf.urls import include,url,patterns from django.contrib import admin admin.autodiscover() url(r'^admin/', include(admin.site.urls)) 成功了
环境是 win10 64 python 2.7.11 django 1.9 使用方法: 第一行 开始from django.conf.urls import include,url,patterns 结束 第二行开始from django.contrib import admin 结束 第三行开始admin.autodiscover()结束 第四行开始url(r'^admin/', include(admin.site.urls)) 结束 成功了 评论不能换行略坑
此处如果报错DoesNotExist at /admin/login/ 应该到INSTALLED APPS里把django.contrib.sites注释掉即可解决
django 1.10 使用方法: 到目前为止,完整的urls.py文件如下 line1:from django.conf.urls import url, include line2:from django.contrib import admin line3:from mysite.views import hello, current_datetime, hours_ahead line4:admin.autodiscover() line5:urlpatterns = [ line6: url(r'^hello/$', hello), line7: url(r'^time/$', current_datetime), line8: url(r'^time/plus/(\d{1,2})/$', hours_ahead), line9: url(r'^admin/', include(admin.site.urls)), line10:]
直接使用默认的就可以,我的是python2版本的django1.9,默认配置url中包含url(r'^admin/$', admin.site.urls),不清楚include是干什么的,我这样就可以了。
urlpatterns = [ url(r'^hello/$', hello), url(r'^time/$',current_datetime), # url(r'^time/plus/\d+/$',hours_ahead), 在URL上增加正则匹配时差数值 url(r'^time/plus/(\d{1,2})/$',hours_ahead), url(r'^admin/',admin.site.urls,name='admin'), #注意2.0必须在后边添加name ] #2.0必须添加app_name app_name = 'books'
2.0 from django.contrib import admin url(r'^admin/',admin.site.urls,name='admin'),
当这一切都配置好后,现在你将发现Django管理工具可以运行了。 启动开发服务器(如前:python manage.py runserver ),然后在浏览器中访问:http://127.0.0.1:8000/admin/
it doesn't work... "TemplateDoesNotExist at /admin/" and it seems the template do exist in "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/admin/login.html"...
python 2.6.6, django 1.4, apache 2 修改/etc/apache2/site-availiables/default,加上对static/admin/静态目录的路由解析: Alias /static/admin /usr/local/lib/python2.6/dist-packages/django/contrib/admin/static/admin <Directory "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/static/admin"> AllowOverride None Options None Order allow,deny Allow from all </Directory> <Location "/static/admin/"> SetHandler None </Location> <LocationMatch "\.(jpg|gif|png|txt|ico|pdf|css|jpeg)$"> SetHandler None </LocationMatch>
发现是因为注释掉MIDDLEWARE_CLASSES中的'django.contrib.auth.middleware.AuthenticationMiddleware'导致
配置好之后,显示 Exception Type: ValueError Exception Value:need more than 1 value to unpack 求解决办法,我用的是Django 1.4.1
报错 NoReverseMatch at /admin/ Reverse for 'logout' with arguments '()' and keyword arguments '{}' not found. 不知道咋解决
运行命令后报以下的错误,请问这要怎么解决? AttributeError at /admin 'HttpResponse' object has no attribute 'rindex' Request Method: GET Request URL: http://127.0.0.1:8000/admin Django Version: 1.5.4 Exception Type: AttributeError Exception Value: 'HttpResponse' object has no attribute 'rindex' Exception Location: C:\Python33\lib\site-packages\django\core\urlresolvers.py in get_mod_func, line 142 Python Executable: C:\Python33\python.exe Python Version: 3.3.2 Python Path: ['D:\\pythonDemo\\djangoDemo\\mysite', 'C:\\WINDOWS\\system32\\python33.zip', 'C:\\Python33\\DLLs', 'C:\\Python33\\lib', 'C:\\Python33', 'C:\\Python33\\lib\\site-packages'] Server time: 星期一, 28 十月 2013 08:53:30 +0800
执行到这一步时报错: AssertionError at / The session-based temporary message storage requires session middleware to be installed, and come before the message middleware in the MIDDLEWARE_CLASSES list. 原来要将 'django.contrib.sessions.middleware.SessionMiddleware' 放在 'django.contrib.messages.middleware.MessageMiddleware' 前面,否则会报错。
显示没有 admin目录的是因为你的 template_dir中没有django的template目录,你可以从你的python安装目录里面的django目录里拷贝一份template到你自己项目的template中就可以了。
这里有些人可能会报错:django no such table: django_session 这是因为启动server的时候数据库还没有已经创建的管理员信息。执行python manage.py syncdb之后python manage.py runserver
Reverse for 'logout' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'admin/(.*)logout/$']咋解决
自己定义了一个templates文件夹后,admin会在这个文件夹下找login.html,没有就会报错。解决办法是在TEMPLATES里加一项,建一个key:value = 'NAME':'admin'
ProgrammingError: (1146, "Table 'mydb.django_session' doesn't exist")我运行了python manage.py migrate 也不行,这个session表还是没建
直接去数据库drop database mydb 然后重新执行makemigrations migrate createsuperuser,去数据库一看发现session表就有了,真TM神奇
,使用管理工具。
管理界面的设计是针对非技术人员的,所以它应该是自我解释的。 尽管如此,这里简单介绍一下它的基本特性。
[Dynamic Language] Python Django: You don't have permission to edit anything 解决办法: http://www.cnblogs.com/abeen/archive/2010/09/12/1824427.html 找到urls.py,将 admin.autodiscover()的注释去掉后权限正常了。
你看到的第一件事是如图6-1所示的登录屏幕。
要在/bin/mysite/books/下建立一个admin.py,否则在admin页面显示不出内容如下: from django.contrib import admin from mysite.books.models import Book, Author, Publisher admin.site.register(Book) admin.site.register(Publisher) admin.site.register(Author)
在urls.py里加入admin.autodiscover(),这样就能够显示Auth:Groups、Users了。 不然按照本文的做法,再进入admin界面之后,我只能看到“You don't have permission to edit anything.”
这个地方有点权限问题,如果是Linux系统的话,可能会出现Template doesn't exist问题,用chmod给dist-packages里的django加上一个权限就可以访问了。
我也出现了css丢失的问题,通过取消setting.py里的django.contrib.staticfiles,这样的话是不是第五章注释掉的东西都取消注释,应该就没什么影响吧???
https://github.com/jacobian/djangobook.com/blob/master/graphics/chapter06/login.png图挂了打上面
没有css,可以找到Python2.7.6\Lib\site.py文件,修改479行encoding = "gbk" # Default value set by _PyUnicode_Init() 重启服务器去看看吧!这是楼上的博客里的
我是ls的 lsss说的文章 http://blog.csdn.net/monkeyduck/article/details/19826421 文章引用的文章 http://blog.webforefront.com/archives/2011/02/python_ascii_co.html 我照着改了个gbk,but,改完过后那个自带的服务器都启动不了了,改回来才有正常了,不知道有人遇到一样的问题不
没有CSS是因为编码问题,在配置文件settings.py中加入; import sys reload(sys) sys.setdefaultencoding('gbk')
图 6-1. Django的登录截图
你要使用你原来设置的超级用户的用户名和密码。 如果无法登录,请运行python manage.py createsuperuser ,确保你已经创建了一个超级用户。
一旦登录了,你将看到管理页面。 这个页面列出了管理工具中可编辑的所有数据类型。 现在,由于我们还没有创建任何模块,所以这个列表只有寥寥数条类目: 它仅有两个默认的管理-编辑模块:用户组(Groups)和用户(Users)。
django 1.3.1 版本,我是url(r'^admin/doc/', include('django.contrib.admindocs.urls')),这行去掉注释。然后,添加admi.py(注意里面的换行)文件,之后可以显示的。“Ch6”被“Books”代替了。
在项目下的urls.py 需要添加一行: admin.autodiscover() 否则出现: you don't have permission to edit anything
加入admin.py: from django.contrib import admin from models import Publisher,Author,Book admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book)
必须在ulrs.py里把 from django.contrib import admin admin.autodiscover() 这两行uncomment掉,才不会出现 you don't have permission to edit anything并看到group那些
出现‘"sites framework" without having set the SITE_ID setting.’错误的,需要在setting中加上SITE_ID=1
drop database mydb,然后重新执行生成库表命令python manage.py migrate,看到返回Apply all migrations: admin, contenttypes, books, auth, sessions,重新创建超级用户python manage.py createsuperuser,然后登录发现可以了
图 6-2。 Django admin的首页
在Django管理页面中,每一种数据类型都有一个 change list 和 edit form 。前者显示数据库中所有的可用对象;后者可让你添加、更改和删除数据库中的某条记录。
其它语言
图片跟官网不一样可能是把比书中setting的INSTALLED_APPS和MIDDLEWARE_CLASSES中的多余的几项给注释掉的原因,去掉注释就ok了
如果你的母语不是英语,而你不想用它来配置你的浏览器,你可以做一个快速更改来观察Django管理工具是否被翻译成你想要的语言。 仅需添加‘django.middleware.locale.LocaleMiddleware’ 到MIDDLEWARE_CLASSES 设置中,并确保它在’django.contrib.sessions.middleware.SessionMiddleware’ 之后 。 (见上)
我发现在IE下可以中文,但是firefox下和chrome下不行,后来firefox下更改了options后就好了,把编码格式改成utf8,语言改成中文,OK;chrome下把语言栏的中文简体拖到最上面,解决。当然Settings里的时区和语言也是要改的
开始显示中文,更改'django.middleware.locale.LocaleMiddleware'后,显示成英文了。。后来发现跟chrome的语言设置有关。
不添加任何东西 把settings.py的LANGUAGE_CODE = 'zh-cn' 这个做法通过。(Python 2.7 Django 1.5 Chrome)
python2.7 django1.3 chrome 我的改了language code=zh-cn就好了, (之前我之前一直被语言困扰,我用Notepad++, 后来发现在格式里面一定要设置utf-8,作用于所有页面),这里就只改一下
Linux 64 Django 1.6 配置 LANGUAGE_CODE = 'zh-cn' TIME_ZONE = 'Asia/Shanghai' 即可显示中文
添加后启动界面提示这,/usr/local/lib/python2.7/site-packages/Django-1.8.1-py2.7.egg/django/utils/translation/__init__.py:146: RemovedInDjango19Warning: The use of the language code 'zh-cn' is deprecated. Please use the 'zh-hans' translation instead.
python3.6+django2.2,折腾了一阵,总算改成中文了。先把Django装成2.1.8版本:pip install django==2.1.8;再设置LANGUAGE_CODE = 'zh-hans';最后设置时区TIME_ZONE = 'Asia/Shanghai' 。大功告成!
使用Python3.7/Django 2.2.4 修改settings.py中的 LANGUAGE_CODE = 'zh-hans' 之前版本可能zh_Hans也是可以的,多试试!!!
完成后,请刷新页面。 如果你设置的语言可用,一系列的链接文字将被显示成这种语言。这些文字包括页面顶端的Change password和Log out,页面中部的Groups和Users。 Django自带了多种语言的翻译。
关于Django更多的国际化特性,请参见第十九章。
点击Uers行中的Change链接,引导用户更改列表。
为什么我这出来的页上没有chang list 和edit form呢,而是在Recent Actions下面提示My Actions None available呢
管理页面丢失css的同学们,把INSTALLED_APPS下边的django.contrib.staticfiles反注释掉。 之前在某一章的时候我记得把那个注释掉了...
根据提示打开 \Python 2.x\lib\mimetypes.py def enum_types(mimedb): i = 0 while True: try: ctype = _winreg.EnumKey(mimedb, i) except EnvironmentError: break #try: #ctype = ctype.encode(default_encoding) # omit in 3.x! #except UnicodeEncodeError: #pass else: yield ctype i += 1
图 6-3. 典型的改变列表视图 (见上)
这个页面显示了数据库中所有的用户。你可以将它看作是一个漂亮的网页版查询:SELECT * FROM auth_user; 如果你一直跟着作练习,并且只添加了一个用户,你会在这个页面中看到一个用户。但是如果你添加了多个用户,你会发现页面中还有过滤器、排序和查询框。 过滤器在右边;排序功能可通过点击列头查看;查询框在页面顶部,它允许你通过用户名查询。
点击其中一个用户名,你会看见关于这个用户的编辑窗口。
图 6-4. 典型的编辑表格 (见上)
这个页面允许你修改用户的属性,如姓名和权限。 (如果要更改用户密码,你必须点击密码字段下的change password form,而不是直接更改字段值中的哈西码。)另外需要注意的是,不同类型的字段会用不同的窗口控件显示。例如,日期/时间型用日历控件,布尔型用复选框,字符型用简单文本框显示。
我编辑一个用户的名字和姓氏,然后点击保存。有报错。后来发现,是添加了django.middleware.locale.LocaleMiddleware这个之后,界面是汉语的错误。注释掉这行就可以了。为什么中文不行呢?
如果在中文下在这里出现 column 'change_messsage' 类的错误(显然是数据库更新有问题),有可能是数据库字符集的问题哦,修改数据库设置即可,和 django 无关。
你可以通过点击编辑页面下方的删除按钮来删除一条记录。 你会见到一个确认页面。有时候,它会显示有哪些关联的对象将会一并被删除。 (例如,如果你要删除一个出版社,它下面所有的图书也将被删除。)
你可以通过点击管理主页面中某个对象的Add来添加一条新记录。 一个空白记录的页面将被打开,等待你填充。
你还能看到管理界面也控制着你输入的有效性。 你可以试试不填必需的栏目或者在时间栏里填错误的时间,你会发现当你要保存时会出现错误信息,如图6-5所示。
图6-5. 编辑表格显示错误信息 (见上)
当你编辑已有的对像时,你在窗口的右上角可以看到一个历史按钮。 通过管理界面做的每一个改变都留有记录,你可以按历史键来检查这个记录(见图6-6)。
图6-6. Django 对像历史页面 (见上)
将你的Models加入到Admin管理中
有一个关键步骤我们还没做。 让我们将自己的模块加入管理工具中,这样我们就能够通过这个漂亮的界面添加、修改和删除数据库中的对象了。 我们将继续第五章中的book 例子。在其中,我们定义了三个模块: Publisher 、 Author 和 Book 。
from django.contrib import admin from books.models import Publisher,Author,Book admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book) django 1.9 books跟mysite同一级目录,所以在admin.py下应该是这样
from django.contrib import admin
from mysite.books.models import Publisher, Author, Book
admin.site.register(Publisher)
admin.site.register(Author)
admin.site.register(Book)
for "from mysite.book.models. import Publisher, Author, Book" there is no mysite before book.models
这里from mysite.books.models import Publisher, Author, Book改为 from books.models import Publisher, Author, Book,不然提示没有books.model
from mysite.books.models import Publisher, Author, Book 应改为 from books.models import Publisher, Author, Book
这里from mysite.books.models import Publisher, Author, Book要改为 from books.models import Publisher, Author, Book,不然提示没有books.model
i think it should be "import models" because admin.py and models.py are in the same director or it will be in a mess
我的层级目录下,admin跟models在books的下一层,同级,所以直接从models import就好。大家注意自己的目录层级关系。 from models import Publisher, Author, Book
这些代码通知管理工具为这些模块逐一提供界面。
完成后,打开页面 [http://127.0.0.1:8000/admin](http://127.0.0.1:8000/admin)/ ,你会看到一个Books区域,其中包含Authors、Books和Publishers。 (你可能需要先停止,然后再启动服务(runserver ),才能使其生效。)
在项目下的urls.py 需要添加一行: admin.autodiscover() 否则出现: you don't have permission to edit anything --摘自前面的评注
在项目下的urls.py 去掉admin.autodiscover()前面的注释,否则出现: you don't have permission to edit anything 而且这条语句一定要放在urlpatterns = patterns前面
提示这玩意,/usr/local/lib/python2.7/site-packages/Django-1.8.1-py2.7.egg/django/utils/translation/__init__.py:146: RemovedInDjango19Warning: The use of the language code 'zh-cn' is deprecated. Please use the 'zh-hans' translation instead.
现在你拥有一个功能完整的管理界面来管理这三个模块了。 很简单吧!
我使用中文出现Warning: Incorrect string value: '\xE9\x82\x93\xE4\xBA\x9A...' for column 'name' at row 1 是怎么回事?
Incorrect string value: '\xE6\xA2\xB5\xE8\x92\x82...' for column 'object_repr' at row 1 这种错误是因为表格的编码不对,设置成UTF-8就可以了。参考:http://www.programgo.com/article/38654863685/
花点时间添加和修改记录,以填充数据库。 如果你跟着第五章的例子一起创建Publisher对象的话(并且没有删除),你会在列表中看到那些记录。
这里需要提到的一个特性是,管理工具处理外键和多对多关系(这两种关系可以在Book 模块中找到)的方法。 作为提醒,这里有个Book 模块的例子:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
在Add book页面中([http://127.0.0.1:8000/admin/books/book/add](http://127.0.0.1:8000/admin/books/book/add)/ ),外键 publisher用一个选择框显示,多对多 字段author用一个多选框显示。 点击两个字段后面的绿色加号,可以让你添加相关的记录。 举个例子,如果你点击Publisher后面的加号,你将会得到一个弹出窗口来添加一个publisher。 当你在那个窗口中成功创建了一个publisher后,Add book表单会自动把它更新到字段上去 花巧.
MessageMiddleware 也必须uncomment掉,否则add book出错: MessageFailure at /admin/books/book/add/ You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
add中文出错的解决办法 centos6下 修改/etc/my.cnf增加 [client] default-character-set=utf8 [mysqld] character_set_server=utf8 init_connect='SET NAMES utf8' 删掉数据库重新建立设置编码为utf-8,同步一下python manage.py syncdb搞定
Admin是如何工作的
在幕后,管理工具是如何工作的呢? 其实很简单。
请教一个问题,这个admin界面上不管选啥语言,最终你能看到的都是"Publisher",在定义表的时候有没有一个类似alias name的功能 我需要显示的是 "出版社" 而不是"Publisher"
楼上那个应该是类名,是管理员用来管理数据库的,就应该是定义它的类的名字,改成中文反而不直观了,要改成中文,估计要在类里设定相应中文,并改admin源代码,我初学,是这么理解的
当服务启动时,Django从url.py 引导URLconf,然后执行admin.autodiscover() 语句。 这个函数遍历INSTALLED_APPS配置,并且寻找相关的 admin.py文件。 如果在指定的app目录下找到admin.py,它就执行其中的代码。
在books 应用程序目录下的admin.py 文件中,每次调用admin.site.register() 都将那个模块注册到管理工具中。 管理工具只为那些明确注册了的模块显示一个编辑/修改的界面。
应用程序django.contrib.auth 包含自身的admin.py ,所以Users和Groups能在管理工具中自动显示。 其它的django.contrib应用程序,如django.contrib.redirects,其它从网上下在的第三方Django应用程序一样,都会自行添加到管理工具。
综上所述,管理工具其实就是一个Django应用程序,包含自己的模块、模板、视图和URLpatterns。 你要像添加自己的视图一样,把它添加到URLconf里面。 你可以在Django基本代码中的django/contrib/admin 目录下,检查它的模板、视图和URLpatterns,但你不要尝试直接修改其中的任何代码,因为里面有很多地方可以让你自定义管理工具的工作方式。 (如果你确实想浏览Django管理工具的代码,请谨记它在读取关于模块的元数据过程中做了些不简单的工作,因此最好花些时间阅读和理解那些代码。)
设置字段可选
在摆弄了一会之后,你或许会发现管理工具有个限制:编辑表单需要你填写每一个字段,然而在有些情况下,你想要某些字段是可选的。 举个例子,我们想要Author模块中的email字段成为可选,即允许不填。 在现实世界中,你可能没有为每个作者登记邮箱地址。
为了指定email字段为可选,你只要编辑Book模块(回想第五章,它在mysite/books/models.py文件里),在email字段上加上blank=True。代码如下:
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(**blank=True** )
注意,这里的**号是提醒你着这个**号之间的代码是新加入的,在拷贝的时候,这个**号要去掉,否则代码会出错。我的机器是win7+python3.3.4+django1.6.2
不要在纠结星号了.. 文章的原始内容是用markdown缩写, 为了突出新增加的内容,使用加粗显示(在待加粗字符两侧各加两个星号.),但是网站并没有使用markdown2htm,所以,原样显示.
这些代码告诉Django,作者的邮箱地址允许输入一个空值。 所有字段都默认blank=False,这使得它们不允许输入空值。
这里会发生一些有趣的事情。 直到现在,除了__unicode__()方法,我们的模块充当数据库中表定义的角色,即本质上是用Python的语法来写CREATE TABLE语句。 在添加blank=True过程中,我们已经开始在简单的定义数据表上扩展我们的模块了。 现在,我们的模块类开始成为一个富含Author对象属性和行为的集合了。 email不但展现为一个数据库中的VARCHAR类型的字段,它还是页面中可选的字段,就像在管理工具中看到的那样。
当你添加blank=True以后,刷新页面Add author edit form (http://127.0.0.1:8000/admin/books/author/add/ ),将会发现Email的标签不再是粗体了。 这意味它不是一个必填字段。 现在你可以添加一个作者而不必输入邮箱地址,即使你为这个字段提交了一个空值,也再不会得到那刺眼的红色信息“This field is required”。
设置日期型和数字型字段可选
虽然blank=True同样适用于日期型和数字型字段,但是这里需要详细讲解一些背景知识。
SQL有指定空值的独特方式,它把空值叫做NULL。NULL可以表示为未知的、非法的、或其它程序指定的含义。
在SQL中, NULL的值不同于空字符串,就像Python中None不同于空字符串("")一样。这意味着某个字符型字段(如VARCHAR)的值不可能同时包含NULL和空字符串。
这会引起不必要的歧义或疑惑。 为什么这条记录有个NULL,而那条记录却有个空字符串? 它们之间有区别,还是数据输入不一致? 还有: 我怎样才能得到全部拥有空值的记录,应该按NULL和空字符串查找么?还是仅按字符串查找?
为了消除歧义,Django生成CREATE TABLE语句自动为每个字段显式加上NOT NULL。 这里有个第五章中生成Author模块的例子:
CREATE TABLE "books_author" (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(40) NOT NULL,
"email" varchar(75) NOT NULL
)
;
在大多数情况下,这种默认的行为对你的应用程序来说是最佳的,因为它可以使你不再因数据一致性而头痛。 而且它可以和Django的其它部分工作得很好。如在管理工具中,如果你留空一个字符型字段,它会为此插入一个空字符串(而 不是NULL)。
但是,其它数据类型有例外:日期型、时间型和数字型字段不接受空字符串。 如果你尝试将一个空字符串插入日期型或整数型字段,你可能会得到数据库返回的错误,这取决于那个数据库的类型。 (PostgreSQL比较严禁,会抛出一个异常;MySQL可能会也可能不会接受,这取决于你使用的版本和运气了。)在这种情况下,NULL是唯一指定空值的方法。 在Django模块中,你可以通过添加null=True来指定一个字段允许为NULL。
因此,这说起来有点复杂: 如果你想允许一个日期型(DateField、TimeField、DateTimeField)或数字型(IntegerField、DecimalField、FloatField)字段为空,你需要使用null=True * 和* blank=True。
为了举例说明,让我们把Book模块修改成允许 publication_date为空。修改后的代码如下:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField(**blank=True, null=True** )
单用none=True是不行的,因为他检查到你为空,所以弹出提示,这个是Django设计的,你肯定要加上blank=True,none=True可有可无,因为数据库肯定是允许none,要不会插入或修改数据报错,这个错误是数据库返回的
添加null=True比添加blank=True复杂。因为null=True改变了数据的语义,即改变了CREATE TABLE语句,把publication_date字段上的NOT NULL删除了。 要完成这些改动,我们还需要更新数据库。
Django1.10版本,这里好像只写blank=Ture就可以啊,如下代码,我测试了没有报错,使用admin管理界面不输入日期也一点问题没有。 class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField(blank=True)
出于某种原因,Django不会尝试自动更新数据库结构。所以你必须执行ALTER TABLE语句将模块的改动更新至数据库。 像先前那样,你可以使用manage.py dbshell进入数据库服务环境。 以下是在这个特殊情况下如何删除NOT NULL:
对应于mysql的语法是 ALTER TABLE books_book change publication_date publication_date date NULL;
@xwj 如果出现错误:Error: You appear not to have the 'sqlite3' program installed or on your path. 解决办法: http://stackoverflow.com/questions/4578231/error-while-accessing-sqlite3-shell-from-django-application
MySQL可以执行: alter table books_book modify column publication_date date default NULL;
Sql Server: ALTER TABLE books_book ALTER COLUMN publication_date date NULL;
提示“'mysql'不是内部或外部命令”的解决办法是设置“E:\Program Files\MySQL\MySQL Server 5.5\bin”到环境变量,然后dos窗口执行“set PATH=C:”
@easongao 提到的方法不错 顺带下一条评论里面的@rex也提到了执行语句的问题,注意这里不是MySQL语句。 先改环境变量,然后D:\djangodocument\mysite>manage.py dbshell mysql> alter table test.books_book modify column publication_date date default n ull; 注意我的数据库名是test,你们的自己改,
我前面步骤都没问题,但是执行manage.py dbshell后,提示:'sqlite3' 不是内部或外部命令,也不是可运行的程序或批处理文件。怎么回事啊? 我是在win7上用PyCharm做的开发。
目前用的Django 1.8 先执行:python manage.py makemigtations 然后:python manage.py syncdb 根据模型修改数据库表,无压力 我叫菜鸟
小菜鸟的拼写有问题。可以看syshu这个,python中是有提示的。 最新版本可以执行makemigrations子命令创建修改,再执行migrate或dbsync子命令应用修改。 具体命令是:python manage.py makemigrations 然后执行:python manage.py migrate(或者python manage.py dbsync)
根据楼上的执行,报错:django.db.utils.OperationalError: (1050, "Table 'books_author' already exists")
重新生成了一遍表就可以了。 第一步,python manage.py makemigrations books 生成需要执行的sql 可以使用 python manage.py sqlmigrate books 0001 查看sql 第二步,python manage.py migrate 同步到数据库 第三步,修改字段属性 python manage.py makemigrations 生成改动的sql,可以使用 python manage.py sqlmigrate books 0002 查看sql 第四步,python manage.py migrate books 更新到数据库
MySql对应的语法应该是:ALTER TABLE books_book CHANGE COLUMN publication_date new_name DATE NULL;
感谢ls,用sqllite3的话先运行 python manage.py makemigrations 然后运行 python manage.py migrate就可以了 不用进dbshell执行alter语句
先运行 python manage.py makemigrations 然后运行 python manage.py migrate 测试date可以为空提交,通过
ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;
mysql对于的语法:ALTER TABLE books_book MODIFY COLUMN publication_date DATE DEFAULT NULL;
Django1.10版本,这里好像只写blank=Ture就可以啊,如下代码,我测试了没有报错,使用admin管理界面不输入日期也一点问题没有。 class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField(blank=True)
(注意:以下SQL语法是PostgreSQL特有的。)
mysql ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;运行出现如何的提示: sql> ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL; ROR 1064 (42000): You have an error in your SQL syntax; check the manual that cor sponds to your MySQL server version for the right syntax to use near 'NOT NULL' a line 1
Mysql的语法,‘django'是我自己的数据库的名字,你可以修改成自己的 ALTER TABLE `django`.`books_book` MODIFY COLUMN `publication_date` DATE DEFAULT NULL;
mysql中应该是这样的 mysql> alter table django.books_book modify column publication_date date default null;
LS的你都用sql改NOT NULL 为 NULL 所以你现在加不加null=True当然可以,但是在你构建models的时候比如建表,数据迁移的时候请一定加上,要不建立的表的字段还是NOT NULL。
我们将在第十章详细讲述数据库结构更改。
关于blank和null,做个简陋的笔记: 1.对于字符串型字段:只需要设置blank=True,无需关心null(事实上django自动添加not null,用来保证空值均为空字符串类型("")从而便于查询),可以随意增加或删掉blank=True选项,无需关心更新数据库。 2.对于日期型和数字型字段:需要同时设置blank=True和null=True,并且如果是后添加或删除的话需要手动更新数据库。(更新数据库参考第十章)
Django1.10版本,这里好像只写blank=Ture就可以啊,如下代码,我测试了没有报错,使用admin管理界面不输入日期也一点问题没有。 class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField(blank=True)
现在让我们回到管理工具,添加book的编辑页面允许输入一个空的publication date。
自定义字段标签
在编辑页面中,每个字段的标签都是从模块的字段名称生成的。 规则很简单: 用空格替换下划线;首字母大写。例如:Book模块中publication_date的标签是Publication date。
然而,字段名称并不总是贴切的。有些情况下,你可能想自定义一个标签。 你只需在模块中指定verbose_name。
举个例子,说明如何将Author.email的标签改为e-mail,中间有个横线。
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, **verbose_name='e-mail'** )
我也遇到models.py里中文编码问题。centos6 系统,如下设置:LANG="en_US.UTF-8" LC_ALL='',models.py(加上# -*- coding: utf-8 -*-) 在windows下用文本转换为UTF-8编码,然后上传到linux上。secureCRT 会话选项--外观 字体编码UTF-8
Django-1.11.3中,只要之前在settings.py中设置过 LANGUAGE_CODE = 'zh-hans',这里的标签就设置为中文后就可以在页面正常显示出来。
文件头指定# -*- coding: utf-8 -*- 然后 email = models.EmailField(u'电子邮箱',blank=True) 就支持了
修改后重启服务器,你会在author编辑页面中看到这个新标签。
请注意,你不必把verbose_name的首字母大写,除非是连续大写(如:"USA state")。Django会自动适时将首字母大写,并且在其它不需要大写的地方使用verbose_name的精确值。
最后还需注意的是,为了使语法简洁,你可以把它当作固定位置的参数传递。 这个例子与上面那个的效果相同。
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(**'e-mail',** blank=True)
可以中文啊,我上面有写:“我也遇到models.py里中文编码问题。centos6 系统,如下设置:LANG="en_US.UTF-8" LC_ALL='',models.py(加上# -*- coding: utf-8 -*-) 在windows下用文本转换为UTF-8编码,然后上传到linux上。secureCRT 会话选项--外观 字体编码UTF-8” windows的未试过
但这不适用于ManyToManyField 和ForeignKey字段,因为它们第一个参数必须是模块类。 那种情形,必须显式使用verbose_name这个参数名称。
自定义ModelAdmi类
并且正好被管理工具使用,而不是专门针对管理工具的..... 意思是说上面讲的内容是与第五章模型相关的,即使不用Admin管理页面也是可以使用的。 这句正好和本章最上面呼应。
迄今为止,我们做的blank=True、null=True和verbose_name修改其实是模块级别,而不是管理级别的。 也就是说,这些修改实质上是构成模块的一部分,并且正好被管理工具使用,而不是专门针对管理工具的。
除了这些,Django还提供了大量选项让你针对特别的模块自定义管理工具。 这些选项都在ModelAdmin classes里面,这些类包含了管理工具中针对特别模块的配置。
自定义列表
让我们更深一步:自定义Author模块的列表中的显示字段。 列表默认地显示查询结果中对象的__unicode__()。 在第五章中,我们定义Author对象的__unicode__()方法,用以同时显示作者的姓和名。
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name='e-mail')
**def __unicode__(self):**
**return u'%s %s' % (self.first_name, self.last_name)**
一直没整明白,python语法中两个**号代表什么意思,这一点好像不符合python的宗旨啊。 这句话 **def __unicode__(self):** 什么意思?大神们回复
结果正如图6-7所示,列表中显示的是每个作者的姓名。
为什么我的作者名字显示都是Author object, 当admin.py加了 class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') 后,显示是根据这显示了, 但是book选项里,还是显示Author object,不显示作者名
@weige 引用stack overflow上的回答: “In Python 2, the object model specifies __str__() and __unicode__() methods. If these methods exist, they must return str (bytes) and unicode (text) respectively. The print statement and the str() built-in call __str__() to determine the human-readable representation of an object. The unicode() built-in calls __unicode__() if it exists, and otherwise falls back to __str__() and decodes the result with the system encoding. Conversely, the Model base class automatically derives __str__() from __unicode__() by encoding to UTF-8. In Python 3, there’s simply __str__(), which must return str (text).” 大意是说python3只能用__str__()
图 6-7. 作者列表
我们可以在这基础上改进,添加其它字段,从而改变列表的显示。 这个页面应该提供便利,比如说:在这个列表中可以看到作者的邮箱地址。如果能按照姓氏或名字来排序,那就更好了。
为了达到这个目的,我们将为Author模块定义一个ModelAdmin类。 这个类是自定义管理工具的关键,其中最基本的一件事情是允许你指定列表中的字段。 打开admin.py并修改:
from django.contrib import admin
from mysite.books.models import Publisher, Author, Book
**class AuthorAdmin(admin.ModelAdmin):**
**list_display = ('first_name', 'last_name', 'email')**
admin.site.register(Publisher)
**admin.site.register(Author, AuthorAdmin)**
admin.site.register(Book)
这里的from mysite.books.models import Publisher, Author, Book也要改成from books.models import Publisher, Author, Book,不然会发生ImportError。
class AuthorAdmin(admin.ModelAdmin)须在admin.site.register(Author, AuthorAdmin)上方?不可在其下方??class须在引用代码的上方定义么,python也是这样么,还是只有django这样??
https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#modeladmin-options 这里可以查询所有的ModelAdmin属性,list_display是其中一个属性。
解释一下代码:
我们新建了一个类AuthorAdmin,它是从django.contrib.admin.ModelAdmin派生出来的子类,保存着一个类的自定义配置,以供管理工具使用。 我们只自定义了一项:list_display, 它是一个字段名称的元组,用于列表显示。 当然,这些字段名称必须是模块中有的。
这个描述看的有点晕。反正折腾后才发现:list_display 可查看页面显示字段的顺序。将代码改成: list_display=('email','first_name','last_name') 再查看页面,email就在第一列了。
我们修改了admin.site.register()调用,在Author后面添加了AuthorAdmin。你可以这样理解: 用AuthorAdmin选项注册Author模块。
admin.site.register()函数接受一个ModelAdmin子类作为第二个参数。 如果你忽略第二个参数,Django将使用默认的选项。Publisher和Book的注册就属于这种情况。
弄好了这个东东,再刷新author列表页面,你会看到列表中有三列:姓氏、名字和邮箱地址。 另外,点击每个列的列头可以对那列进行排序。 (参见图 6-8)
我的情况是‘list_display’这个属性如果变成别的名,比如‘display’,就不显示,改回‘list_display’就能显示。看来是规定死的东西。
图 6-8. 修改后的author列表页面
接下来,让我们添加一个快速查询栏。 向AuthorAdmin追加search_fields,如:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')
**search_fields = ('first_name', 'last_name')**
刷新浏览器,你会在页面顶端看到一个查询栏。 (见图6-9.)我们刚才所作的修改列表页面,添加了一个根据姓名查询的查询框。 正如用户所希望的那样,它是大小写敏感,并且对两个字段检索的查询框。如果查询"bar",那么名字中含有Barney和姓氏中含有Hobarson的作者记录将被检索出来。
图 6-9. 含search_fields的author列表页面
接下来,让我们为Book列表页添加一些过滤器。
不好意思,上面我的描述有问题。其实是publication_date,这个参数加入到list_display和list_filter中的时候会报错,提示他不是一个可调用的( which is not a callable,...),有没有大神解释一下是怎么回事吗?英语不好,看文档也没查到。
from django.contrib import admin
from mysite.books.models import Publisher, Author, Book
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')
search_fields = ('first_name', 'last_name')
**class BookAdmin(admin.ModelAdmin):**
**list_display = ('title', 'publisher', 'publication_date')**
**list_filter = ('publication_date',)**
admin.site.register(Publisher)
admin.site.register(Author, AuthorAdmin)
**admin.site.register(Book, BookAdmin)**
这里注意,关系键不能作为serach_fields 即,由于【publisher】是Book的外键,如果在BookAdmin中添加search_fields=('publisher',)的话就会报错。如果想根据publisher搜索的话,可以用:list_filter = ('publication_date','publisher')
用外键作为search_list 元组会如此报错TypeError: Related Field has invalid lookup: icontains
由于我们要处理一系列选项,因此我们创建了一个单独的ModelAdmin类:BookAdmin。首先,我们定义一个list_display,以使得页面好看些。 然后,我们用list_filter这个字段元组创建过滤器,它位于列表页面的右边。 Django为日期型字段提供了快捷过滤方式,它包含:今天、过往七天、当月和今年。这些是开发人员经常用到的。 图 6-10显示了修改后的页面。
图 6-10. 含过滤器的book列表页面
过滤器 同样适用于其它类型的字段,而不单是日期型 (请在布尔型 和外键 字段上试试)。当有两个以上值时,过滤器就会显示。
另外一种过滤日期的方式是使用date_hierarchy选项,如:
增加了这行代码后,页面出以下错误: DatabaseError at /admin/books/book/ Incorrect datetime value: '%Y-%m-%d 00:00:00' 我使用的是MySQL作为数据库和MySQL官方的connector,有知道怎么解决的吗?
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
**date_hierarchy = 'publication_date'**
使用date_hierarchy时,如果数据库中publication_date字段对应没有值(有一个值即可不报错),会报错。因此要使用date_hierarchy时,最好还是设置字段为not null比较好。
修改好后,页面中的列表顶端会有一个逐层深入的导航条,效果如图 6-11. 它从可用的年份开始,然后逐层细分到月乃至日。
图 6-11. 含date_hierarchy的book列表页面
请注意,date_hierarchy接受的是 字符串 ,而不是元组。因为只能对一个日期型字段进行层次划分。
最后,让我们改变默认的排序方式,按publication date降序排列。 列表页面默认按照模块class Meta(详见第五章)中的ordering所指的列排序。但目前没有指定ordering值,所以当前排序是没有定义的。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
**ordering = ('-publication_date',)**
这个ordering选项基本像模块中class Meta的ordering那样工作,除了它只用列表中的第一个字段名。 如果要实现降序,仅需在传入的列表或元组的字段前加上一个减号(-)。
刷新book列表页面观看实际效果。 注意Publication date列头现在有一个小箭头显示排序。 (见图 6-12.)
图 6-12 含排序的book列表页面
我们已经学习了主要的选项。 通过使用它们,你可以仅需几行代码就能创建一个功能强大、随时上线的数据编辑界面。
自定义编辑表单
正如自定义列表那样,编辑表单多方面也能自定义。
首先,我们先自定义字段顺序。 默认地,表单中的字段顺序是与模块中定义是一致的。 我们可以通过使用ModelAdmin子类中的fields选项来改变它:
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
**fields = ('title', 'authors', 'publisher', 'publication_date')**
there is no comma behind 'publication_date' at the 2nd line,but there is a comma behind 'publication_date' at the 3rd line. why?
Django 1.5.2 没有fields选项,用list_display实现。并且显示author列时 由于多对多的关系 会报错。这个多对多的关系是在建表时候导致的么?求解释和解决方法
关于怎么在大家理解的list那个页面里面显示author,解决方法是在Book加个method,例如: class Book(models.Model): authors = models.ManyToManyField(Author) def get_authors(self): return ','.join([p.first_name for p in self.authors.all()]) 然后在admin.py里,在bookadmin的fields里面加个钩子,例如: fields = ('title', 'get_authors')
完成之后,编辑表单将按照指定的顺序显示各字段。 它看起来自然多了——作者排在书名之后。 字段顺序当然是与数据条目录入顺序有关, 每个表单都不一样。
通过fields这个选项,你可以排除一些不想被其他人编辑的fields 只要不选上不想被编辑的field(s)即可。 当你的admi用户只是被信任可以更改你的某一部分数据时,或者,你的数据被一些外部的程序自动处理而改变了了,你就可以用这个功能。 例如,在book数据库中,我们可以隐藏publication_date,以防止它被编辑。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
**fields = ('title', 'authors', 'publisher')**
这样,在编辑页面就无法对publication date进行改动。 如果你是一个编辑,不希望作者推迟出版日期的话,这个功能就很有用。 (当然,这纯粹是一个假设的例子。)
去掉publication_date后在添加书的时候日期选项,创建成功后也是空值 这样就可以通过查询历史发现书被添加的时间了,但是就算是在publication_date可选的时候查看历史中添加书的时间也是系统时间啊,不知道为什么说可以促使作者出书
这说的是pubulication_date不能被change,也就是http://127.0.0.1:8000/admin/books/book/1/change/这个页面中不显示这一项,但是在http://127.0.0.1:8000/admin/books/book/这个页面上是有pubulication_date日期的,以此来说出版时间被确定而不能被修改。
当一个用户用这个不包含完整信息的表单添加一本新书时,Django会简单地将publication_date设置为None,以确保这个字段满足null=True的条件。
另一个常用的编辑页面自定义是针对多对多字段的。 真如我们在book编辑页面看到的那样,多对多字段 被展现成多选框。虽然多选框在逻辑上是最适合的HTML控件,但它却不那么好用。 如果你想选择多项,你必须还要按下Ctrl键(苹果机是command键)。 虽然管理工具因此添加了注释(help_text),但是当它有几百个选项时,它依然显得笨拙。
更好的办法是使用filter_horizontal。让我们把它添加到BookAdmin中,然后看看它的效果。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
**filter_horizontal = ('authors',)**
list_display = ('title','authors','publisher','publication_date') 加了一个,'authors' 就报错了,搞不懂为什么
如果在authors使用verbose_name='作者'用了中文,设置filter_horizontal后界面上该字段什么都没有,应该用verbose_name='作者'.decode('utf8')
<class 'books.admin.BookAdmin'>: (admin.E109) The value of 'list_display[1]' must not be a ManyToManyField.
(如果你一着跟着做练习,请注意移除fields选项,以使得编辑页面包含所有字段。)
刷新book编辑页面,你会看到Author区中有一个精巧的JavaScript过滤器,它允许你检索选项,然后将选中的authors从Available框移到Chosen框,还可以移回来。
当authors 添加了自定义标签verbose_name='作者' 为中文的时候, javascript 过滤器显示不出来 确实是,verbose_name只能为英文
没有效果的,因为你你们从头到尾都没有打开静态的css和js,你们没有发现每次你们连接上网站的时候,有http 404 的错误吗?提示没有找到css和js。因为admin管理站点的css和js没有加载,所以看到的效果没有英文版图片上的那么绚丽。做法: 1.在setting.py的INSTALL_APP下入'django.contrib.staticfiles'。 2.在setting.PY中加入 STATIC_ROOT = '/static/'一行,然后运行python manage.py collectstatic,这样会把安装在你的python目录下的django包中的css和js复制到你当前盘的根目录下的文件夹static中。 3.把上面得到的static文件夹移动到外层的mysite/下就好了。因为STATIC_URL是指明了找这些文件的路径。
图 6-13. 含filter_horizontal的book编辑页面
我们强烈建议针对那些拥有十个以上选项的多对多字段 使用filter_horizontal。 这比多选框好用多了。 你可以在多个字段上使用filter_horizontal,只需在这个元组中指定每个字段的名字。
ModelAdmin类还支持filter_vertical选项。 它像filter_horizontal那样工作,除了控件都是垂直排列,而不是水平排列的。 至于使用哪个,只是个人喜好问题。
filter_horizontal和filter_vertical选项只能用在多对多字段 上, 而不能用于 ForeignKey字段。 默认地,管理工具使用下拉框 来展现外键 字段。但是,正如多对多字段 那样,有时候你不想忍受因装载并显示这些选项而产生的大量开销。 例如,我们的book数据库膨胀到拥有数千条publishers的记录,以致于book的添加页面装载时间较久,因为它必须把每一个publishe都装载并显示在下拉框 中。
解决这个问题的办法是使用raw_id_fields 选项。它是一个包含外键字段名称的元组,它包含的字段将被展现成文本框 ,而不再是下拉框 。见图 6-14。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
filter_horizontal = ('authors',)
**raw_id_fields = ('publisher',)**
图 6-14. 含raw_id_fields的book编辑页面
在这个输入框中,你输入什么呢? publisher的数据库ID号。 考虑到人们通常不会记住这些数据库ID,管理工具提供了一个放大镜图标方便你输入。点击那个图标将会弹出一个窗口,在那里你可以选择想要添加的publishe。
我照着这个做,可是看不到available框、chosen框,也看不到文本框,这里的图还挂了。郁闷阿~ 我在manytomany字段里添有blank=True,这个有影响吗
我觉得这个做得很不好,比如说选择后一般用户都是期待上屏的是选择时显示的值,可能把id放在隐藏框里比较好吧,另外右边的字段没有变化好像也不太好。
点击那个放大镜就会跳入新的页面,在那里会看到相应的ID号和publisher,放大镜后面的是当时的publisher,确定之前是不会跟着所选的ID号改变的!!!LS误会了
楼上,因为css与js都没加载。 在 settings.py的INSTALLED_APPS中加入django.contrib.staticfiles即可解决
setting.py/////import sys/// reload(sys)/// sys.setdefaultencoding('gbk')/////
@all我终于搞定了,因为admin管理站点的css和js没有加载,所以看到的效果没有英文版图片上的那么绚丽。做法: 1.在setting.py的INSTALL_APP下入'django.contrib.staticfiles'。 2.在setting.PY中加入 STATIC_ROOT = '/static/'一行,然后运行python manage.py collectstatic,这样会把安装在你的python目录下的django包中的css和js复制到你当前盘的根目录下的文件夹static中。 3.把上面得到的static文件夹移动到外层的mysite/下就好了。因为STATIC_URL是指明了找这些文件的路径。
django1.10版本,为何我这么做了,admin页面没有反应? from django.contrib import admin from books.models import * class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields = ('first_name', 'last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date') ordering = ('-publication_date') class PublisherAdmin(admin.ModelAdmin): list_display = ('name','address','city','state_province','country','website') admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book) ~
用户、用户组和权限
因为你是用超级用户登录的,你可以创建,编辑和删除任何对像。 然而,不同的环境要求有不同的权限,系统不允许所有人都是超级用户。 管理工具有一个用户权限系统,通过它你可以根据用户的需要来指定他们的权限,从而达到部分访问系统的目的。
用户帐号应该是通用的、独立于管理界面以外仍可以使用。但我们现在把它看作是管理界面的一部分。 在第十四章,我们将讲述如何把用户帐号与你的网站(不仅仅是管理工具)集成在一起。
你通过管理界面编辑用户及其许可就像你编辑别的对象一样。 我们在本章的前面,浏览用户和用户组区域的时候已经见过这些了。 如你所想,用户对象有标准的用户名、密码、邮箱地址和真实姓名,同时它还有关于使用管理界面的权限定义。 首先,这有一组三个布尔型标记:
- 活动标志,它用来控制用户是否已经激活。 如果一个用户帐号的这个标记是关闭状态,而用户又尝试用它登录时,即使密码正确,他也无法登录系统。
- 成员标志,它用来控制这个用户是否可以登录管理界面(即:这个用户是不是你们组织里的成员) 由于用户系统可以被用于控制公众页面(即:非管理页面)的访问权限(详见第十四章),这个标志可用来区分公众用户和管理用户。
- 超级用户标志,它赋予用户在管理界面中添加、修改和删除任何项目的权限。 如果一个用户帐号有这个标志,那么所有权限设置(即使没有)都会被忽略。
普通的活跃,非超级用户的管理用户可以根据一套设定好的许可进入。 管理界面中每种可编辑的对象(如:books、authors、publishers)都有三种权限: 创建 许可, 编辑 许可和 删除 许可。 给一个用户授权许可也就表明该用户可以进行许可描述的操作。
当你创建一个用户时,它没有任何权限,该有什么权限是由你决定的。 例如,你可以给一个用户添加和修改publishers的权限,而不给他删除的权限。 请注意,这些权限是定义在模块级别上,而不是对象级别上的。据个例子,你可以让小强修改任何图书,但是不能让他仅修改由机械工业出版社出版的图书。 后面这种基于对象级别的权限设置比较复杂,并且超出了本书的覆盖范围,但你可以在Django documentation中寻找答案。
据个例子,你可以让小强修改任何图书,但是不能让他仅修改由机械工业出版社出版的图书。 这句比较拗口我整理一下:你可以“让小强拥有修改所有书的权限吧!”,而不能“让小强只拥有修改机械工业出版社的图书的权限!”
so they let you say “John can make changes to any book,” but they don’t let you say “John can make changes to any book published by Apress.”
注释
权限管理系统也控制编辑用户和权限。 如果你给某人编辑用户的权限,他可以编辑自己的权限,这种能力可能不是你希望的。 赋予一个用户修改用户的权限,本质上说就是把他变成一个超级用户。
你也可以给组中分配用户。 一个 组 简化了给组中所有成员应用一套许可的动作。 组在给大量用户特定权限的时候很有用。
何时、为什么使用管理界面?何时又不使用呢?
经过这一章的学习,你应该对Django管理工具有所认识。 但是我们需要表明一个观点: 什么时候 、 为什么 用,以及什么时候又 不 用。
Django的管理界面对非技术用户要输入他们的数据时特别有用;事实上这个特性就是专门为这个 实现的。 在Django最开始开发的新闻报道的行业应用中,有一个典型的在线自来水的水质专题报道 应用,它的实现流程是这样的:
- 负责这个报道的记者和要处理数据的开发者碰头,提供一些数据给开发者。
- 开发者围绕这些数据设计模型然后配置一个管理界面给记者。
- 记者检查管理界面,尽早指出缺少或多余的字段。 开发者来回地修改模块。
- 当模块认可后,记者就开始用管理界面输入数据。 同时,程序员可以专注于开发公众访问视图和模板(有趣的部分)。
换句话说,Django的管理界面为内容输入人员和编程人员都提供了便利的工具。
当然,除了数据输入方面,我们发现管理界面在下面这些情景中也是很有用的:
- 检查模块* :当你定义好了若干个模块,在管理页面中把他们调出来然后输入一些虚假的数据,这是相当有用的。 有时候,它能显示数据建模的错误或者模块中其它问题。
- 管理既得数据* :如果你的应用程序依赖外部数据(来自用户输入或网络爬虫),管理界面提供了一个便捷的途径,让你检查和编辑那些数据。 你可以把它看作是一个功能不那么强大,但是很方便的数据库命令行工具。
- 临时的数据管理程序* :你可以用管理工具建立自己的轻量级数据管理程序,比如说开销记录。 如果你正在根据自己的,而不是公众的需要开发些什么,那么管理界面可以带给你很大的帮助。 从这个意义上讲,你可以把它看作是一个增强的关系型电子表格。
最后一点要澄清的是: 管理界面不是终结者。 过往许多年间,我们看到它被拆分、修改成若干个功能模块,而这些功能不是它所支持的。 它不应成为一个 公众 数据访问接口,也不应允许对你的数据进行复杂的排序和查询。 正如本章开头所说,它仅提供给可信任的管理员。 请记住这一点,它是有效使用管理界面的钥匙。