ID |
English原文 |
中文翻译 |
最近翻译记录 |
状态 |
操作 |
0#翻译 |
Chapter 12: Sessions, Users, and Registration
---------------------------------------------
|
十二章: Sessions, Users和 Registration
--------------------------------------------- |
4094天前 |
Jasemin |
翻译 |
1#翻译 |
Its time for a confession: weve been deliberately ignoring an incredibly important
aspect of Web development prior to this point. So far, weve thought of the traffic
visiting our sites as some faceless, anonymous mass hurtling itself against our
carefully designed pages.
|
是时候承认了:我们有意的避开了web开发中极其重要的方面。到目前为止,我们都在假定,网站流量是大量的匿名用户带来的。 |
5825天前 |
|
翻译 |
2#翻译 |
This isnt true, of course. The browsers hitting our sites have real humans behind
them (some of the time, at least). Thats a big thing to ignore: the Internet is at
its best when it serves to connect *people* , not machines. If were going to develop
truly compelling sites, eventually were going to have to deal with the bodies behind
the browsers.
|
这当然不对,浏览器的背后都是活生生的人(至少某些时候是)。我们忽略了一件重要的事情:互联网服务于人而不是机器。要开发一个真正令人心动的网站,我们必须面对浏览器后面活生生的人。 |
6135天前 |
Greta |
翻译 |
3#翻译 |
Unfortunately, its not all that easy. HTTP is designed to be *stateless* that is,
each and every request happens in a vacuum. Theres no persistence between one
request and the next, and we cant count on any aspects of a request (IP address,
user agent, etc.) to consistently indicate successive requests from the same person.
|
很不幸,这并不容易。HTTP被设计为"无状态",每次请求都处于相同的空间中。在一次请求和下一次请求之间没有任何状态保持,我们无法根据请求的任何方面(IP地址,用户代理等)来识别来自同一人的连续请求。 |
6140天前 |
Giggles |
翻译 |
4#翻译 |
In this chapter youll learn how to handle this lack of state. Well start at the
lowest level (*cookies* ), and work up to the high-level tools for handling
sessions, users and registration.
|
在本章中你将学会如何搞定状态的问题。好了,我们会从较低的层次(*cookies*)开始,然后过渡到用高层的工具来搞定会话,用户和注册的问题。 |
6140天前 |
|
翻译 |
5#翻译 |
Cookies
```````
|
Cookies
``````` |
6139天前 |
|
翻译 |
6#翻译 |
Browser developers long ago recognized that HTTPs statelessness poses a huge problem
for Web developers, and thus *cookies* were born. A cookie is a small piece of
information that browsers store on behalf of Web servers. Every time a browser
requests a page from a certain server, it gives back the cookie that it initially
received.
|
浏览器的开发者在很早的时候就已经意识到, HTTP's 的无状态会对Web开发者带来很大的问题,于是(*cookies*)应运而生。cookies 是浏览器为 Web 服务器存储的一小段信息。每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的cookies |
6042天前 |
|
翻译 |
7#翻译 |
Lets take a look how this might work. When you open your browser and type in
``google.com`` , your browser sends an HTTP request to Google that starts something
like this:
|
来看看它是怎么工作的。当你打开浏览器并访问 ``google.com`` ,你的浏览器会给Google发送一个HTTP请求,起始部分就象这样: |
5963天前 |
Brandi |
翻译 |
10#翻译 |
When Google replies, the HTTP response looks something like the following:
|
当 Google响应时,HTTP的响应是这样的: |
6140天前 |
|
翻译 |
13#翻译 |
Notice the ``Set-Cookie`` header. Your browser will store that cookie value
(``PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671`` ) and serve it back to
Google every time you access the site. So the next time you access Google, your
browser is going to send a request like this:
|
注意 ``Set-Cookie`` 的头部。你的浏览器会存储cookie值( ``PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671`` ) ,而且每次访问google 站点都会回送这个cookie值。因此当你下次访问Google时,你的浏览器会发送像这样的请求: |
6086天前 |
Allayna |
翻译 |
16#翻译 |
Google then can use that ``Cookie`` value to know that youre the same person who
accessed the site earlier. This value might, for example, be a key into a database
that stores user information. Google could (and does) use it to display your name on
the page.
|
于是 ``Cookies`` 的值会告诉Google,你就是早些时候访问过Google网站的人。这个值可能是数据库中存储用户信息的key,可以用它在页面上显示你的用户名。 |
6086天前 |
Tyanne |
翻译 |
17#翻译 |
Getting and Setting Cookies
'''''''''''''''''''''''''''
|
存取Cookies
'''''''''''' |
6140天前 |
|
翻译 |
18#翻译 |
When dealing with persistence in Django, most of the time youll want to use the
higher-level session and/or user frameworks discussed a little later in this
chapter. However, well pause and look at how to read and write cookies at a low
level. This should help you understand how the rest of the tools discussed in the
chapter actually work, and it will come in handy if you ever need to play with
cookies directly.
|
在Django中处理持久化,大部分时候你会更愿意用高层些的session 和/或 后面要讨论的user 框架。但在此之前,我们需要停下来在底层看看如何读写cookies。这会帮助你理解本章节后面要讨论的工具是如何工作的,而且如果你需要自己操作cookies,这也会有所帮助。 |
6140天前 |
Zavrina |
翻译 |
19#翻译 |
Reading cookies that are already set is incredibly simple. Every request object has
a ``COOKIES`` object that acts like a dictionary; you can use it to read any cookies
that the browser has sent to the view:
|
读取已经设置好的cookies极其简单,每个request对象都有一个 ``COOKIES`` 对象,可以象使用字典般使用它,你可以读取任何浏览器发给视图(view)的任何cookies: |
5963天前 |
Amber |
翻译 |
22#翻译 |
Writing cookies is slightly more complicated. You need to use the ``set_cookie()``
method on an ``HttpResponse`` object. Heres an example that sets the
``favorite_color`` cookie based on a ``GET`` parameter:
|
写cookies稍微复杂点,需要用 ``HttpResponse`` 对象的 ``set_cookie()`` 方法来写。这儿有个基于 ``GET`` 参数来设置 ``favorite_color`` cookie的例子: |
5963天前 |
|
翻译 |
25#翻译 |
You can also pass a number of optional arguments to ``response.set_cookie()`` that
control aspects of the cookie, as shown in Table 12-1.
|
你可以给 ``response.set_cookie()`` 传递一些可选的参数来控制cookie的行为,详见表12-1。 |
5933天前 |
|
翻译 |
26#翻译 |
.. table:: Table 12-1: Cookie options
+-----------+---------+------------------------------------------------------------+
|Parameter |Default |Description |
+===========+=========+============================================================+
|``max_age``|``None`` |Age (in seconds) that the cookie should last. If this |
| | |parameter is ``None`` , the cookie will last only until the |
| | |browser is closed. |
+-----------+---------+------------------------------------------------------------+
|``expires``|``None`` |The actual date/time when the cookie should expire. It needs|
| | |to be in the format ``"Wdy, DD-Mth-YY HH:MM:SS GMT"`` . If |
| | |given, this parameter overrides the ``max_age`` parameter. |
+-----------+---------+------------------------------------------------------------+
|``path`` |``"/"`` |The path prefix that this cookie is valid for. Browsers will|
| | |only pass the cookie back to pages below this path prefix, |
| | |so you can use this to prevent cookies from being sent to |
| | |other sections of your site. |
| | | |
| | |This is especially useful when you dont control the top |
| | |level of your sites domain. |
+-----------+---------+------------------------------------------------------------+
|``domain`` |``None`` |The domain that this cookie is valid for. You can use this |
| | |parameter to set a cross-domain cookie. For example, |
| | |``domain=".example.com"`` will set a cookie that is readable|
| | |by the domains ``www.example.com`` , ``www2.example.com`` , |
| | |and ``an.other.sub.domain.example.com`` . |
| | | |
| | |If this parameter is set to ``None`` , a cookie will only be|
| | |readable by the domain that set it. |
+-----------+---------+------------------------------------------------------------+
|``secure`` |``False``|If set to ``True`` , this parameter instructs the browser to|
| | |only return this cookie to pages accessed over HTTPS. |
+-----------+---------+------------------------------------------------------------+
|
.. table:: 表 12-1: Cookie 选项
+-----------+---------+------------------------------------------------------------+
|参数 |缺省值 |描述 |
+===========+=========+============================================================+
|``max_age``|``None`` |cookies的持续有效时间(以秒计),如果设置为 ``None`` cookies|
| | |在浏览器关闭的时候就失效了。 |
+-----------+---------+------------------------------------------------------------+
|``expires``|``None`` |cookies的过期时间,格式: ``"Wdy, DD-Mth-YY HH:MM:SS GMT"`` |
| | |如果设置这个参数,它将覆盖 ``max_age`` 参数。 |
+-----------+---------+------------------------------------------------------------+
|``path`` |``"/"`` |cookie生效的路径前缀,浏览器只会把cookie回传给带有该路径的页|
| | |面,这样你可以避免将cookie传给站点中的其他的应用。 |
| | | |
| | |当你的应用不处于站点顶层的时候,这个参数会非常有用。 |
+-----------+---------+------------------------------------------------------------+
|``domain`` |``None`` |cookie生效的站点。你可用这个参数来构造一个跨站cookie。如, |
| | |``domain=".example.com"`` 所构造的cookie对下面这些站点都是可|
| | |读的: ``www.example.com`` 、 ``www2.example.com`` 和 |
| | |``an.other.sub.domain.example.com`` 。 |
| | | |
| | |如果该参数设置为 ``None`` ,cookie只能由设置它的站点读取。 |
+-----------+---------+------------------------------------------------------------+
|``secure`` |``False``|如果设置为 ``True`` ,浏览器将通过HTTPS来回传cookie。 |
+-----------+---------+------------------------------------------------------------+
|
5933天前 |
Joni |
翻译 |
29#翻译 |
The Mixed Blessing of Cookies
'''''''''''''''''''''''''''''
|
好坏参半的Cookies
''''''''''''''''' |
6139天前 |
Demarlo |
翻译 |
30#翻译 |
You might notice a number of potential problems with the way cookies work. Lets look
at some of the more important ones:
|
也许你已经注意到了,cookies的工作方式可能导致的问题,一起来看看其中一些重要的方面: |
6139天前 |
|
翻译 |
31#翻译 |
Storage of cookies is essentially voluntary; browsers dont guarantee anything.
In fact, all browsers enable users to control the policy for accepting cookies.
If you want to see just how vital cookies are to the Web, try turning on your
browsers prompt to accept every cookie option.
|
cookies存取完全是非强制性的,浏览器不保证这一点。事实上,所有的浏览器都让用户自己控制
是否接受cookies。如果你想知道cookies对于web应用有多重要,你可以试着打开这个浏览器的
选项:提示我接受每次cookie。 |
6139天前 |
Keiwan |
翻译 |
32#翻译 |
Despite their nearly universal use, cookies are still the definition of
unreliability. This means that developers should check that a user actually
accepts cookies before relying on them.
|
尽管cookies广为使用,但仍被认为是不可靠的的。这意味着,开发者使用cookies之前必须
检查用户是否可以接收cookie。 |
6139天前 |
Bette |
翻译 |
33#翻译 |
More important, you should *never* store important data in cookies. The Web is
filled with horror stories of developers whove stored unrecoverable information
in browser cookies only to have that data purged by the browser for one reason
or another.
|
更重要的是,*永远* 也不要在cookie中存储重要的数据。开发者在cookie中存储了不可恢复
的数据,而浏览器却因为某种原因将cookie中的数据清得一干二净,这样令人发指的故事在
Web世界中比比皆是。 |
6139天前 |
Happy |
翻译 |
34#翻译 |
Cookies (especially those not sent over HTTPS) are not secure. Because HTTP data
is sent in cleartext, cookies are extremely vulnerable to snooping attacks. That
is, an attacker snooping on the wire can intercept a cookie and read it. This
means you should never store sensitive information in a cookie.
|
Cookie(特别是那些没通过HTTPS传输的)是非常不安全的。因为HTTP数据是以明文发送的,所以
特别容易受到嗅探攻击。也就是说,嗅探攻击者可以在网络中拦截并读取cookies,因此你要
绝对避免在cookies中存储敏感信息。 |
6139天前 |
|
翻译 |
35#翻译 |
Theres an even more insidious attack, known as a *man-in-the-middle* attack,
wherein an attacker intercepts a cookie and uses it to pose as another user.
Chapter 19 discusses attacks of this nature in depth, as well as ways to prevent
it.
|
还有一种被称为"中间人"的攻击更阴险,攻击者拦截一个cookie并将其用于另一个用户。
第19章将深入讨论这种攻击的本质以及如何避免。 |
6139天前 |
|
翻译 |
36#翻译 |
Cookies arent even secure from their intended recipients. Most browsers provide
easy ways to edit the content of individual cookies, and resourceful users can
always use tools like mechanize ( `http://wwwsearch.sourceforge.net/mechanize/`_ )
to construct HTTP requests by hand.
|
即使从预想中的接收者返回的cookie也是不安全的,因为大多数浏览器都提供了很方便的方法来
修改cookies的内容,有技术背景的用户甚至可以用像mechanize
( `http://wwwsearch.sourceforge.net/mechanize/`_ )
这样的工具来手工构造HTTP请求。 |
6137天前 |
|
翻译 |
37#翻译 |
So you cant store data in cookies that might be sensitive to tampering. The
canonical mistake in this scenario is storing something like ``IsLoggedIn=1`` in
a cookie when a user logs in. Youd be amazed at the number of sites that make
mistakes of this nature; it takes only a second to fool these sites security
systems.
|
因此不能在cookies中存储可能会被篡改的敏感数据,“经典”错误是:在cookies中存储
``IsLoggedIn=1`` ,以标识用户已经登录。犯这类错误的站点数量多的令人难以置信;
绕过这些网站的安全系统也是易如反掌。 |
6137天前 |
|
翻译 |
38#翻译 |
Djangos Session Framework
`````````````````````````
|
Django的 Session 框架
````````````````````` |
4154天前 |
|
翻译 |
39#翻译 |
With all of these limitations and potential security holes, its obvious that cookies
and persistent sessions are examples of those pain points in Web development. Of
course, Djangos goal is to be an effective painkiller, so it comes with a session
framework designed to smooth over these difficulties for you.
|
由于存在的限制与安全漏洞,cookies和持续性会话已经成为Web开发中令人头疼的典范。好消息是,Django的目标正是高效的“头疼杀手”,它自带的session框架会帮你搞定这些问题。 |
6137天前 |
|
翻译 |
40#翻译 |
This session framework lets you store and retrieve arbitrary data on a per-site
visitor basis. It stores data on the server side and abstracts the sending and
receiving of cookies. Cookies use only a hashed session IDnot the data itselfthus
protecting you from most of the common cookie problems.
|
你可以用session 框架来存取每个访问者任意数据,这些数据在服务器端存储,并用通过cookie来传输数据摘要。cookies只存储数据的哈希会话ID,而不是数据本身,从而避免了大部分的常见cookie问题。 |
6137天前 |
Jerry |
翻译 |
41#翻译 |
Lets look at how to enable sessions and use them in views.
|
下面我们来看看如何打开session功能,并在视图中使用它。 |
6137天前 |
|
翻译 |
42#翻译 |
Enabling Sessions
'''''''''''''''''
|
打开 Sessions功能
''''''''''''''''' |
6139天前 |
|
翻译 |
43#翻译 |
Sessions are implemented via a piece of middleware (see Chapter 15) and a Django
model. To enable sessions, youll need to follow these steps:
|
Sessions 功能是通过一个中间件(middleware)和一个模型(model)来实现的。要打开sessions功能,需要以下几步操作: |
6137天前 |
Lisa |
翻译 |
44#翻译 |
1. Edit your ``MIDDLEWARE_CLASSES`` setting and make sure ``MIDDLEWARE_CLASSES``
contains ``'django.contrib.sessions.middleware.SessionMiddleware'`` .
|
1. 编辑 ``MIDDLEWARE_CLASSES`` 配置,确保 ``MIDDLEWARE_CLASSES`` 中包含 ``'django.contrib.sessions.middleware.SessionMiddleware'`` |
6086天前 |
|
翻译 |
45#翻译 |
2. Make sure ``'django.contrib.sessions'`` is in your ``INSTALLED_APPS`` setting
(and run ``manage.py syncdb`` if you have to add it).
|
2. 确认 ``INSTALLED_APPS`` 中有 ``'django.contrib.sessions'`` (如果你是刚打开这个应用,别忘了运行 ``manage.py syncdb`` ) |
6086天前 |
|
翻译 |
46#翻译 |
The default skeleton settings created by ``startproject`` have both of these bits
already installed, so unless youve removed them, you probably dont have to change
anything to get sessions to work.
|
如果项目是用 ``startproject`` 来创建的,配置文件中都已经安装了这些东西,除非你自己删除,正常情况下,你无需任何设置就可以使用session功能。 |
5958天前 |
Melly |
翻译 |
47#翻译 |
If you dont want to use sessions, you might want to remove the ``SessionMiddleware``
line from ``MIDDLEWARE_CLASSES`` and ``'django.contrib.sessions'`` from your
``INSTALLED_APPS`` . It will save you only a small amount of overhead, but every
little bit counts.
|
如果不需要session功能,你可以删除 ``MIDDLEWARE_CLASSES`` 设置中的 ``SessionMiddleware`` 和 ``INSTALLED_APPS`` 设置中的 ``'django.contrib.sessions'`` 。虽然这只会节省很少的开销,但积少成多啊。 |
5958天前 |
|
翻译 |
48#翻译 |
Using Sessions in Views
'''''''''''''''''''''''
|
在视图中使用Session
''''''''''''''''''''''' |
6111天前 |
Eloise |
翻译 |
49#翻译 |
When ``SessionMiddleware`` is activated, each ``HttpRequest`` objectthe first
argument to any Django view functionwill have a ``session`` attribute, which is a
dictionary-like object. You can read it and write to it in the same way youd use a
normal dictionary. For example, in a view you could do stuff like this:
|
``SessionMiddleware`` 激活后,每个传给视图(view)函数的第一个参数``HttpRequest`` 对象都有一个 ``session`` 属性,这是一个字典型的对象。你可以象用普通字典一样来用它。例如,在视图(view)中你可以这样用: |
5573天前 |
|
翻译 |
52#翻译 |
You can also use other mapping methods like ``keys()`` and ``items()`` on
``request.session`` .
|
其他的映射方法,如 ``keys()`` 和 ``items()`` 对 ``request.session`` 同样有效: |
6086天前 |
|
翻译 |
53#翻译 |
There are a couple of simple rules for using Djangos sessions effectively:
|
下面是一些有效使用Django sessions的简单规则: |
6137天前 |
Nikki |
翻译 |
54#翻译 |
* Use normal Python strings as dictionary keys on ``request.session`` (as opposed
to integers, objects, etc.). This is more of a convention than a hard-and-fast
rule, but its worth following.
|
* 用正常的字符串作为key来访问字典 ``request.session`` , 而不是整数、对象或其它什么的。
这不是什么强硬的条规,但值得遵循。 |
6086天前 |
Nona |
翻译 |
55#翻译 |
* Session dictionary keys that begin with an underscore are reserved for internal
use by Django. In practice, the framework uses only a small number of
underscore-prefixed session variables, but unless you know what they all are
(and you are willing to keep up with any changes in Django itself), staying away
from underscore prefixes will keep Django from interfering with your
application.
|
* Session字典中以下划线开头的key值是Django内部保留key值。框架只会用很少的几个下划线
开头的session变量,除非你知道他们的具体含义,而且愿意跟上Django的变化,否则,最好
不要用这些下划线开头的变量,它们会让Django搅乱你的应用。 |
6137天前 |
|
翻译 |
56#翻译 |
* Dont replace ``request.session`` with a new object, and dont access or set its
attributes. Use it like a Python dictionary.
|
* 不要用一个新对象来替换掉 ``request.session`` ,也不要存取其属性,象用普通Python字典一样用它。 |
5958天前 |
Bubbie |
翻译 |
57#翻译 |
Lets take a look at a few quick examples. This simplistic view sets a
``has_commented`` variable to ``True`` after a user posts a comment. Its a simple
(but not particularly secure) way of preventing a user from posting more than one
comment:
|
我们来看个简单的例子。这是个简单到不能再简单的例子:在用户发了一次评论后将 ``has_commented`` 设置为 ``True`` ,这是个简单(但不很安全)的、防止用户多次评论的方法。 |
5958天前 |
Caiya |
翻译 |
60#翻译 |
This simplistic view logs in a member of the site:
|
下面是一个很简单的站点登录视图(view): |
6137天前 |
|
翻译 |
63#翻译 |
And this one logs out a member, according to ``login()`` :
|
这是退出登录,根据 ``login()`` : |
6086天前 |
Geri |
翻译 |
66#翻译 |
Note
|
注意 |
6137天前 |
Gracye |
翻译 |
67#翻译 |
In practice, this is a lousy way of logging users in. The authentication framework
discussed shortly handles this task for you in a much more robust and useful manner.
These examples are deliberately simplistic so that you can easily see whats going
on.
|
在实践中,这是很烂的用户登录方式,稍后讨论的认证(authentication )框架会帮你以更健壮和有利的方式来处理这些问题。这些非常简单的例子只是想让你知道这一切是如何工作的。 |
6137天前 |
Caiya |
翻译 |
68#翻译 |
Setting Test Cookies
''''''''''''''''''''
|
设置测试Cookies
'''''''''''''''''''' |
6139天前 |
Agatha |
翻译 |
69#翻译 |
As just mentioned, you cant rely on every browser accepting cookies. So, as a
convenience, Django provides an easy way to test whether a users browser accepts
cookies. You just need to call ``request.session.set_test_cookie()`` in a view, and
check ``request.session.test_cookie_worked()`` in a subsequent viewnot in the same
view call.
|
就像前面提到的,你不能指望所有的浏览器都可以接受cookie,因此,Django为了方便,也提供了检查用户浏览器是否接受cookie的简单方法。你只需在视图(view)中调用 ``request.session.set_test_cookie()`` ,并在后续的视图(view)、而不是当前的视图(view)中检查 ``request.session.test_cookie_worked()`` 。 |
5963天前 |
|
翻译 |
70#翻译 |
This awkward split between ``set_test_cookie()`` and ``test_cookie_worked()`` is
necessary due to the way cookies work. When you set a cookie, you cant actually tell
whether a browser accepted it until the browsers next request.
|
虽然把 ``set_test_cookie()`` 和 ``test_cookie_worked()`` 分开的做法看起来有些笨拙,但由于cookie的工作方式,这无可避免。当设置一个cookie时候,只能等浏览器下次访问的时候,你才能知道浏览器是否接受cookie。 |
5963天前 |
Symona |
翻译 |
71#翻译 |
Its good practice to use ``delete_test_cookie()`` to clean up after yourself. Do
this after youve verified that the test cookie worked.
|
检查cookie是否可以正常工作后,你得自己用 ``delete_test_cookie()`` 来清除它,这是个好习惯。 |
5963天前 |
Melia |
翻译 |
72#翻译 |
Heres a typical usage example:
|
这是个典型例子: |
6135天前 |
Essie |
翻译 |
75#翻译 |
Note
|
注意 |
6135天前 |
|
翻译 |
76#翻译 |
Again, the built-in authentication functions handle this check for you.
|
再次强调,内置的认证函数会帮你做检查的。 |
5621天前 |
Jaylen |
翻译 |
77#翻译 |
Using Sessions Outside of Views
'''''''''''''''''''''''''''''''
|
在视图(View)外使用Session
'''''''''''''''''''''''''' |
6139天前 |
|
翻译 |
78#翻译 |
Internally, each session is just a normal Django model defined in
``django.contrib.sessions.models`` . Each session is identified by a more-or-less
random 32-character hash stored in a cookie. Because its a normal model, you can
access sessions using the normal Django database API:
|
从内部来看,每个session都只是一个普通的Django model(在 ``django.contrib.sessions.models`` 中定义)。每个session都由一个随机的32字节哈希串来标识,并存储于数据库中。由于这是一个普通的model,你可以用一般的Django 数据库API来读取session。 |
5963天前 |
Cornelia |
翻译 |
81#翻译 |
Youll need to call ``get_decoded()`` to get the actual session data. This is
necessary because the dictionary is stored in an encoded format:
|
你得用 ``get_decoded()`` 来读取实际的session数据,因为session字典经过了编码存储。 |
5963天前 |
|
翻译 |
84#翻译 |
When Sessions Are Saved
'''''''''''''''''''''''
|
何时保存Session
'''''''''''''''' |
6139天前 |
Lotta |
翻译 |
85#翻译 |
By default, Django only saves to the database if the session has been modified that
is, if any of its dictionary values have been assigned or deleted:
|
缺省的情况下,Django只会在session发生变化的时候才会存入数据库,比如说,字典赋值或删除。 |
6135天前 |
|
翻译 |
88#翻译 |
To change this default behavior, set ``SESSION_SAVE_EVERY_REQUEST`` to ``True`` . If
``SESSION_SAVE_EVERY_REQUEST`` is ``True`` , Django will save the session to the
database on every single request, even if it wasnt changed.
|
你可以设置 ``SESSION_SAVE_EVERY_REQUEST`` 为 ``True`` 来改变这一缺省行为。如果 ``SESSION_SAVE_EVERY_REQUEST`` 设置为 ``True`` ,Django 会在每次请求的时候都把session存到数据库中,即使没有任何改变。 |
5963天前 |
Trixie |
翻译 |
89#翻译 |
Note that the session cookie is sent only when a session has been created or
modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True`` , the session cookie will be
sent on every request. Similarly, the ``expires`` part of a session cookie is
updated each time the session cookie is sent.
|
注意,会话cookie只会在创建和修改的时候才会送出。但如果 ``SESSION_SAVE_EVERY_REQUEST`` 设置为 ``True`` ,会话cookie会在每次请求的时候都会送出。同时,每次会话cookie送出的时候,其 ``expires`` 参数都会更新。 |
5963天前 |
|
翻译 |
90#翻译 |
Browser-Length Sessions vs. Persistent Sessions
'''''''''''''''''''''''''''''''''''''''''''''''
|
浏览器关闭即失效会话 vs. 持久会话
''''''''''''''''''''''''''''''''''
|
6135天前 |
|
翻译 |
91#翻译 |
You might have noticed that the cookie Google sent us contained ``expires=Sun,
17-Jan-2038 19:14:07 GMT;`` . Cookies can optionally contain an expiration date that
advises the browser on when to remove the cookie. If a cookie doesnt contain an
expiration value, the browser will expire it when the user closes his or her browser
window. You can control the session frameworks behavior in this regard with the
``SESSION_EXPIRE_AT_BROWSER_CLOSE`` setting.
|
你可能注意到了,Google给我们发送的cookie中有 ``expires=Sun,
17-Jan-2038 19:14:07 GMT;`` cookie可以有过期时间,这样浏览器就知道什么时候可以删除cookie了。如果cookie没有设置过期时间,当用户关闭浏览器的时候,cookie就自动过期了。你可以改变 ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` 的设置来控制session框架的这一行为。 |
5963天前 |
|
翻译 |
92#翻译 |
By default, ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``False`` , which means
session cookies will be stored in users browsers for ``SESSION_COOKIE_AGE`` seconds
(which defaults to two weeks, or 1,209,600 seconds). Use this if you dont want
people to have to log in every time they open a browser.
|
缺省情况下, ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` 设置为 ``False`` ,这样,会话cookie可以在用户浏览器中保持有效达 ``SESSION_COOKIE_AGE`` 秒(缺省设置是两周,即1,209,600 秒)。如果你不想用户每次打开浏览器都必须重新登陆的话,用这个参数来帮你。 |
5958天前 |
|
翻译 |
93#翻译 |
If ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``True`` , Django will use
browser-length cookies.
|
如果 ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` 设置为 ``True`` ,当浏览器关闭时,Django会使cookie失效。 |
5958天前 |
Krisalyn |
翻译 |
94#翻译 |
Other Session Settings
''''''''''''''''''''''
|
其他的Session设置
'''''''''''''''''''''' |
6086天前 |
Lynsey |
翻译 |
95#翻译 |
Besides the settings already mentioned, a few other settings influence how Djangos
session framework uses cookies, as shown in Table 12-2.
|
除了上面提到的设置,还有一些其他的设置可以影响Django session框架如何使用cookie,详见表 12-2. |
6086天前 |
|
翻译 |
96#翻译 |
.. table:: Table 12-2. Settings that influence cookiebehavior
+-------------------------+----------------------------------------+---------------+
|Setting |Description |Default |
+=========================+========================================+===============+
|``SESSION_COOKIE_DOMAIN``|The domain to use for session cookies. |``None`` |
| |Set this to a string such as | |
| |``".lawrence.com"`` for cross-domain | |
| |cookies, or use ``None`` for a standard | |
| |cookie. | |
+-------------------------+----------------------------------------+---------------+
|``SESSION_COOKIE_NAME`` |The name of the cookie to use for |``"sessionid"``|
| |sessions. This can be any string. | |
+-------------------------+----------------------------------------+---------------+
|``SESSION_COOKIE_SECURE``|Whether to use a secure cookie for the |``False`` |
| |session cookie. If this is set to | |
| |``True`` , the cookie will be marked as | |
| |secure, which means that browsers will | |
| |ensure that the cookie is only sent via | |
| |HTTPS. | |
+-------------------------+----------------------------------------+---------------+
|
.. table:: 表 12-2. 影响cookie行为的设置
+-------------------------+----------------------------------------+---------------+
|设置 |描述 |缺省值 |
+=========================+========================================+===============+
|``SESSION_COOKIE_DOMAIN``|session cookie生效的站点,跨站点生效的 |``None`` |
| |cookie可以这样设置:``".lawrence.com"`` | |
| |``None`` 为标准cookie | |
+-------------------------+----------------------------------------+---------------+
|``SESSION_COOKIE_NAME`` |用于session 的cookie名称,可以是任何 |``"sessionid"``|
| |字符串 | |
+-------------------------+----------------------------------------+---------------+
|``SESSION_COOKIE_SECURE``|是否在session中使用安全cookie,如果设置 |``False`` |
| |``True`` , cookie就会标记为安全, | |
| |这意味着cookie只会通过HTTPS来传输 | |
+-------------------------+----------------------------------------+---------------+
|
6086天前 |
|
翻译 |
99#翻译 |
Technical Details
|
技术细节 |
6135天前 |
Roseanna |
翻译 |
100#翻译 |
For the curious, here are a few technical notes about the inner workings of the
session framework:
|
如果你还是好奇的话,下面是一些关于session框架内部工作方式的技术细节: |
6135天前 |
|
翻译 |
101#翻译 |
The session dictionary accepts any Python object capable of being pickled. See
the documentation for Pythons built-in ``pickle`` module for information about
how this works.
|
session 字典和普通Python对象一样,支持序列化,详见Python文档中内置 ``pickle`` 模块的部分。 |
5963天前 |
|
翻译 |
102#翻译 |
Session data is stored in a database table named ``django_session`` .
|
Session 数据存在数据库表 ``django_session`` 中 |
5963天前 |
|
翻译 |
103#翻译 |
Session data is fetched upon demand. If you never access ``request.session`` ,
Django wont hit that database table.
|
Session 数据在需要的时候才会读取,如果你从不使用 ``request.session`` ,
Django不会动相关数据库表的一根毛。 |
6120天前 |
|
翻译 |
104#翻译 |
Django only sends a cookie if it needs to. If you dont set any session data, it
wont send a session cookie (unless ``SESSION_SAVE_EVERY_REQUEST`` is set to
``True`` ).
|
Django 只在需要的时候才送出cookie。如果你压根儿就没有设置任何会话数据,它不会
送出会话cookie(除非 ``SESSION_SAVE_EVERY_REQUEST`` 设置为 ``True`` ) |
5963天前 |
|
翻译 |
105#翻译 |
The Django sessions framework is entirely, and solely, cookie based. It does not
fall back to putting session IDs in URLs as a last resort, as some other tools
(PHP, JSP) do.
|
Django session 框架完全而且只能基于cookie,不会后退到把会话ID编码在URL中。(像某些工具(PHP,JSP)那样) |
5653天前 |
|
翻译 |
106#翻译 |
This is an intentional design decision. Putting sessions in URLs dont just make
URLs ugly, but also make your site vulnerable to a certain form of session ID
theft via the ``Referer`` header.
|
这是一个有意而为之的设计,把session放在URL中不只是难看,更重要的是这让你的站点
很容易受到攻击——通过 ``Referer`` header进行session ID"窃听"而实施的攻击。 |
5963天前 |
|
翻译 |
107#翻译 |
If youre still curious, the source is pretty straightforward; look in
``django.contrib.sessions`` for more details.
|
如果你还是好奇,阅读源代码是最直接办法,详见 ``django.contrib.sessions`` 。 |
5958天前 |
|
翻译 |
108#翻译 |
Users and Authentication
````````````````````````
|
用户与Authentication
````````````````````````
|
5987天前 |
|
翻译 |
109#翻译 |
Were now halfway to linking browsers directly to Real People. Sessions give us a way
of persisting data through multiple browser requests; the second part of the
equation is using those sessions for user login. Of course, we cant just trust that
users are who they say they are, so we need to authenticate them along the way.
|
现在,我们通过浏览器连接真实用户的目标已经完成一半了。通过session,我们可以在多次浏览器请求中保持数据, 接下来的部分就是用session来处理用户登录了。当然,不能仅凭用户的一面之词,我们就相信,所以我们需要认证。 |
5983天前 |
|
翻译 |
110#翻译 |
Naturally, Django provides tools to handle this common task (and many others).
Djangos user authentication system handles user accounts, groups, permissions, and
cookie-based user sessions. This system is often referred to as an *auth/auth*
(authentication and authorization) system. That name recognizes that dealing with
users is often a two-step process. We need to
|
当然了,Django 也提供了工具来处理这样的常见任务(就像其他常见任务一样)。Django 用户认证系统处理用户帐号,组,权限以及基于cookie的用户会话。这个系统一般被称为 *auth/auth* (认证与授权)系统,这个系统的名称同时也表明了用户常见的两步处理。我们需要 |
6127天前 |
|
翻译 |
111#翻译 |
1. Verify (*authenticate* ) that a user is who he or she claims to be (usually by
checking a username and password against a database of users)
|
1. 验证 (*认证*) 用户是否是他所宣称的用户(一般通过查询数据库验证其用户名和密码) |
6127天前 |
|
翻译 |
112#翻译 |
2. Verify that the user is *authorized* to perform some given operation (usually by
checking against a table of permissions)
|
2. 验证用户是否拥有执行某种操作的 *授权* (通常会通过检查一个权限表来确认) |
6127天前 |
|
翻译 |
113#翻译 |
Following these needs, Djangos auth/auth system consists of a number of parts:
|
根据这些需求,Django 认证/授权 系统会包含以下的部分: |
6127天前 |
|
翻译 |
114#翻译 |
* *Users* : People registered with your site
|
* *用户* : 在网站注册的人 |
6127天前 |
|
翻译 |
115#翻译 |
* *Permissions* : Binary (yes/no) flags designating whether a user may perform a
certain task
|
* *权限* : 用于标识用户是否拥有某种操作的二进制(yes/no)标志 |
6127天前 |
|
翻译 |
116#翻译 |
* *Groups* : A generic way of applying labels and permissions to more than one
user
|
* *组* :一种可以将标记和权限应用于多个用户的常用方法 |
6127天前 |
|
翻译 |
117#翻译 |
* *Messages* : A simple way to queue and display system messages to users
|
* *Messages* : 向用户显示队列式的系统消息的常用方法 |
6127天前 |
|
翻译 |
118#翻译 |
* *Profiles* : A mechanism to extend the user object with custom fields
|
* *Profiles* : 通过自定义字段扩展用户对象的机制 |
6127天前 |
|
翻译 |
119#翻译 |
If youve used the admin tool (detailed in Chapter 6), youve already seen many of
these tools, and if youve edited users or groups in the admin tool, youve actually
been editing data in the auth systems database tables.
|
如果你已经用了admin工具(详见第6章),就会看见这些工具的大部分。如果已经用了admin工具来编辑用户和组,你实际上就已经在编辑认证系统中数据库表。 |
6127天前 |
|
翻译 |
120#翻译 |
Enabling Authentication Support
'''''''''''''''''''''''''''''''
|
打开认证支持
'''''''''''' |
6127天前 |
|
翻译 |
121#翻译 |
Like the session tools, authentication support is bundled as a Django application in
``django.contrib`` , which needs to be installed. Like the session system, its also
installed by default, but if youve removed it, youll need to follow these steps to
install it:
|
像session工具一样,认证支持也是一个Django应用,放在 ``django.contrib`` 中,所以也需要安装。与session系统相似,它也是缺省安装的,但如果它已经被删除了,通过以下步骤也能重新安装上: |
5963天前 |
|
翻译 |
122#翻译 |
1. Make sure the session framework is installed as described earlier in this
chapter. Keeping track of users obviously requires cookies, and thus builds on
the session framework.
|
1. 根据本章早前的部分确认已经安装了session 框架,需要确认用户使用cookie,这样sesson 框架才能正常使用。 |
6127天前 |
|
翻译 |
123#翻译 |
2. Put ``'django.contrib.auth'`` in your ``INSTALLED_APPS`` setting and run
``manage.py syncdb`` .
|
2. 将 ``'django.contrib.auth'`` 放在你的 ``INSTALLED_APPS`` 设置中,然后运行 ``manage.py syncdb`` |
5963天前 |
|
翻译 |
124#翻译 |
3. Make sure that ``'django.contrib.auth.middleware.AuthenticationMiddleware'`` is
in your ``MIDDLEWARE_CLASSES`` setting*after* ``SessionMiddleware`` .
|
3. 确认 ``SessionMiddleware`` 后面的 ``MIDDLEWARE_CLASSES`` 设置中包含 ``'django.contrib.auth.middleware.AuthenticationMiddleware'`` |
5963天前 |
|
翻译 |
125#翻译 |
With that installation out of the way, were ready to deal with users in view
functions. The main interface youll use to access users within a view is
``request.user`` ; this is an object that represents the currently logged-in user.
If the user isnt logged in, this will instead be an ``AnonymousUser`` object (see
below for more details).
|
这样安装后,我们就可以在视图(view)的函数中用处理user了。在视图中存取users,主要用 ``request.user`` ;这个对象表示当前已登录的用户,如果用户还没登录,这就是一个 ``匿名`` 对象(细节见下) |
5963天前 |
|
翻译 |
126#翻译 |
You can easily tell if a user is logged in with the ``is_authenticated()`` method:
|
你可以很容易的通过 ``is_authenticated()`` 方法来判断一个用户是否已经登录了 |
5963天前 |
|
翻译 |
129#翻译 |
Using Users
'''''''''''
|
使用User对象
''''''''''''' |
6120天前 |
|
翻译 |
130#翻译 |
Once you have a ``User`` often from ``request.user`` , but possibly through one of
the other methods discussed shortlyyou have a number of fields and methods available
on that object. ``AnonymousUser`` objects emulate *some* of this interface, but not
all of it, so you should always check ``user.is_authenticated()`` before assuming
youre dealing with a bona fide user object. Tables 12-3 and 12-4 list the fields and
methods, respectively, on ``User`` objects.
|
``User`` 实例一般从 ``request.user`` ,或是其他下面即将要讨论到的方法取得,它有很多属性和方法。
``AnonymousUser`` 对象模拟了 *部分* 的接口,但不是全部,在把它当成真正的user对象
使用前,你得检查一下 ``user.is_authenticated()`` |
6120天前 |
|
翻译 |
131#翻译 |
.. table:: Table 12-3. Fields on ``User`` Objects
+----------------+-----------------------------------------------------------------+
|Field |Description |
+================+=================================================================+
|``username`` |Required; 30 characters or fewer. Alphanumeric characters only |
| |(letters, digits, and underscores). |
+----------------+-----------------------------------------------------------------+
|``first_name`` |Optional; 30 characters or fewer. |
+----------------+-----------------------------------------------------------------+
|``last_name`` |Optional; 30 characters or fewer. |
+----------------+-----------------------------------------------------------------+
|``email`` |Optional. Email address. |
+----------------+-----------------------------------------------------------------+
|``password`` |Required. A hash of, and metadata about, the password (Django |
| |doesnt store the raw password). See the Passwords section for |
| |more about this value. |
+----------------+-----------------------------------------------------------------+
|``is_staff`` |Boolean. Designates whether this user can access the admin site. |
+----------------+-----------------------------------------------------------------+
|``is_active`` |Boolean. Designates whether this account can be used to log in. |
| |Set this flag to ``False`` instead of deleting accounts. |
+----------------+-----------------------------------------------------------------+
|``is_superuser``|Boolean. Designates that this user has all permissions without |
| |explicitly assigning them. |
+----------------+-----------------------------------------------------------------+
|``last_login`` |A datetime of the users last login. This is set to the current |
| |date/time by default. |
+----------------+-----------------------------------------------------------------+
|``date_joined`` |A datetime designating when the account was created. This is set |
| |to the current date/time by default when the account is created. |
+----------------+-----------------------------------------------------------------+
|
.. table:: 表 12-3. ``User`` 对象属性
+----------------+-----------------------------------------------------------------+
|属性 |描述 |
+================+=================================================================+
|``username`` |必填; 少于等于30字符. 只允许字符,数字,下划线 |
+----------------+-----------------------------------------------------------------+
|``first_name`` |可选; 少于等于30字符. |
+----------------+-----------------------------------------------------------------+
|``last_name`` |可选; 少于等于30字符. |
+----------------+-----------------------------------------------------------------+
|``email`` |可选. 邮件地址. |
+----------------+-----------------------------------------------------------------+
|``password`` |必填. 密码的摘要hash(Django不会存储原始密码),详见密码章节部分 |
+----------------+-----------------------------------------------------------------+
|``is_staff`` |布尔值. 用户是否拥有网站的管理权限. |
+----------------+-----------------------------------------------------------------+
|``is_active`` |布尔值. 是否允许用户登录, 设置为``False``,可以不用删除用户来禁止|
| |用户登录 |
+----------------+-----------------------------------------------------------------+
|``is_superuser``|布尔值. 用户是否拥有所有权限,而无需任何显式的权限分配定义 |
+----------------+-----------------------------------------------------------------+
|``last_login`` |用户最后登录的时间,缺省会设置为当前时间 |
+----------------+-----------------------------------------------------------------+
|``date_joined`` |创建用户的时间,当用户创建时,缺省的设置为当前的时间 |
+----------------+-----------------------------------------------------------------+ |
5722天前 |
johnanz |
翻译 |
134#翻译 |
.. table:: Table 12-4. Methods on ``User`` Objects
+-------------------------------+--------------------------------------------------+
|Method |Description |
+===============================+==================================================+
|``is_authenticated()`` |Always returns ``True`` for real ``User`` objects.|
| |This is a way to tell if the user has been |
| |authenticated. This does not imply any |
| |permissions, and it doesnt check if the user is |
| |active. It only indicates that the user has |
| |sucessfully authenticated. |
+-------------------------------+--------------------------------------------------+
|``is_anonymous()`` |Returns ``True`` only for ``AnonymousUser`` |
| |objects (and ``False`` for real ``User`` objects).|
| |Generally, you should prefer using |
| |``is_authenticated()`` to this method. |
+-------------------------------+--------------------------------------------------+
|``get_full_name()`` |Returns the ``first_name`` plus the ``last_name`` |
| |, with a space in between. |
+-------------------------------+--------------------------------------------------+
|``set_password(passwd)`` |Sets the users password to the given raw string, |
| |taking care of the password hashing. This doesnt |
| |actually save the ``User`` object. |
+-------------------------------+--------------------------------------------------+
|``check_password(passwd)`` |Returns ``True`` if the given raw string is the |
| |correct password for the user. This takes care of |
| |the password hashing in making the comparison. |
+-------------------------------+--------------------------------------------------+
|``get_group_permissions()`` |Returns a list of permission strings that the user|
| |has through the groups he or she belongs to. |
+-------------------------------+--------------------------------------------------+
|``get_all_permissions()`` |Returns a list of permission strings that the user|
| |has, both through group and user permissions. |
+-------------------------------+--------------------------------------------------+
|``has_perm(perm)`` |Returns ``True`` if the user has the specified |
| |permission, where ``perm`` is in the format |
| |``"package.codename"`` . If the user is inactive, |
| |this method will always return ``False`` . |
+-------------------------------+--------------------------------------------------+
|``has_perms(perm_list)`` |Returns ``True`` if the user has *all* of the |
| |specified permissions. If the user is inactive, |
| |this method will always return ``False`` . |
+-------------------------------+--------------------------------------------------+
|``has_module_perms(app_label)``|Returns ``True`` if the user has any permissions |
| |in the given ``app_label`` . If the user is |
| |inactive, this method will always return ``False``|
| |. |
+-------------------------------+--------------------------------------------------+
|``get_and_delete_messages()`` |Returns a list of ``Message`` objects in the users|
| |queue and deletes the messages from the queue. |
+-------------------------------+--------------------------------------------------+
|``email_user(subj, msg)`` |Sends an email to the user. This email is sent |
| |from the ``DEFAULT_FROM_EMAIL`` setting. You can |
| |also pass a third argument, ``from_email`` , to |
| |override the From address on the email. |
+-------------------------------+--------------------------------------------------+
|``get_profile()`` |Returns a site-specific profile for this user. See|
| |the Profiles section for more on this method. |
+-------------------------------+--------------------------------------------------+
|
.. table:: 表 12-4. ``User`` 对象方法
+-------------------------------+--------------------------------------------------+
|方法 |描述 |
+===============================+==================================================+
|``is_authenticated()`` |如果是真正的 ``User`` 对象,返回值恒为 ``True`` 。|
| |用于检查用户是否已经通过了认证。通过认证并不意味着|
| |用户拥有任何权限,甚至也不检查该用户是否处于激活状|
| |态,这只是表明用户成功的通过了认证。 |
+-------------------------------+--------------------------------------------------+
|``is_anonymous()`` |如果是个 ``AnonymousUser`` ,返回值为 ``True`` , |
| |如果是 ``User`` 对象,返回值为 ``False`` 。一般来 |
| |说, ``is_authenticated()`` 会比这个方法更常用些。|
+-------------------------------+--------------------------------------------------+
|``get_full_name()`` |返回值为: ``first_name`` 加上 ``last_name`` ,以 |
| |空格分隔。 |
+-------------------------------+--------------------------------------------------+
|``set_password(passwd)`` |将用户的密码设置为给定的字符串,实际密码已被哈希 |
| |处理。这时并不会真正保存 ``User`` 对象。 |
+-------------------------------+--------------------------------------------------+
|``check_password(passwd)`` |如果给定的字符串通过了密码检查,返回 ``True`` 。 |
| |密码比较已进行了哈希处理。 |
+-------------------------------+--------------------------------------------------+
|``get_group_permissions()`` |返回用户通过所属组获得的权限列表 |
+-------------------------------+--------------------------------------------------+
|``get_all_permissions()`` |返回用户通过所属组和用户自身权限所获得的所有权限 |
| |列表。 |
+-------------------------------+--------------------------------------------------+
|``has_perm(perm)`` |如果用户拥有给定的权限,返回 ``True`` , ``perm`` |
| |应形如 ``"package.codename"`` 的格式。如果用户处于|
| |非激活状态,则总是返回 ``False`` 。 |
+-------------------------------+--------------------------------------------------+
|``has_perms(perm_list)`` |如果用户拥有所有给定的权限,返回 ``True`` 。 |
| |如果用户处于非激活状态,则总是返回 ``False`` 。 |
+-------------------------------+--------------------------------------------------+
|``has_module_perms(app_label)``|如果用户拥有任何给定 ``app_label`` 的权限,返回 |
| |``True`` 。如果用户处于非激活状态,则总是返回 |
| |``False`` |
+-------------------------------+--------------------------------------------------+
|``get_and_delete_messages()`` |返回用户的 ``Message`` 对象列表,并从队列中删除。 |
+-------------------------------+--------------------------------------------------+
|``email_user(subj, msg)`` |给用户发送电子邮件,用 ``DEFAULT_FROM_EMAIL`` 的设|
| |置作为发件人。也可以用第3个参数 ``from_email`` 来 |
| |覆盖设置。 |
+-------------------------------+--------------------------------------------------+
|``get_profile()`` |返回用户的网站自定义profile,详见Profile章节 |
+-------------------------------+--------------------------------------------------+ |
5933天前 |
|
翻译 |
137#翻译 |
Finally, ``User`` objects have two many-to-many fields: ``groups`` and
``permissions`` . ``User`` objects can access their related objects in the same way
as any other many-to-many field:
|
最后, ``User`` 对象有两个多对多的属性: ``groups`` 和 ``permissions`` 。 ``User`` 对象可以
象使用其他多对多属性的方法一样使用它们。 |
5963天前 |
|
翻译 |
140#翻译 |
Logging In and Out
''''''''''''''''''
|
登录和退出
'''''''''''''''''' |
6121天前 |
|
翻译 |
141#翻译 |
Django provides built-in view functions for handling logging in and out (and a few
other nifty tricks), but before we get to those, lets take a look at how to log
users in and out by hand. Django provides two functions to perform these actions in
``django.contrib.auth`` : ``authenticate()`` and ``login()`` .
|
Django 提供内置的视图(view)函数用于处理登录和退出 (以及其他奇技淫巧),但在开始前,我们来看看如何手工登录和退出,Django 在 ``django.contrib.auth`` 中提供了两个函数来处理这些事情—— ``authenticate()`` 和 ``login()`` 。 |
5963天前 |
|
翻译 |
142#翻译 |
To authenticate a given username and password, use ``authenticate()`` . It takes two
keyword arguments, ``username`` and ``password`` , and it returns a ``User`` object
if the password is valid for the given username. If the password is invalid,
``authenticate()`` returns ``None`` :
|
认证给出的用户名和密码,使用 ``authenticate()`` 函数。它接受两个参数,用户名 ``username`` 和 密码 ``password`` ,并在密码对用给出的用户名是合法的情况下返回一个 ``User`` 对象。当给出的密码不合法的时候 ``authenticate()`` 函数返回 ``None`` : |
6113天前 |
|
翻译 |
145#翻译 |
``authenticate()`` only verifies a users credentials. To log in a user, use
``login()`` . It takes an ``HttpRequest`` object and a ``User`` object and saves the
users ID in the session, using Djangos session framework.
|
``authenticate()`` 只是验证一个用户的证书而已。而要登录一个用户,使用
``login()`` 。该函数接受一个 ``HttpRequest`` 对象和一个 ``User`` 对象作为参数并使用Django的会话( ``session`` )框架把用户的ID保存在该会话中。 |
6113天前 |
|
翻译 |
146#翻译 |
This example shows how you might use both ``authenticate()`` and ``login()`` within
a view function:
|
下面的例子演示了如何在一个视图中同时使用 ``authenticate()`` 和 ``login()`` 函数: |
6113天前 |
|
翻译 |
149#翻译 |
To log out a user, use ``django.contrib.auth.logout()`` within your view. It takes
an ``HttpRequest`` object and has no return value:
|
注销一个用户,在你的视图中使用 ``django.contrib.auth.logout()`` 。该函数接受一个 ``HttpRequest`` 对象作为参数,没有返回值。 |
6113天前 |
|
翻译 |
152#翻译 |
Note that ``logout()`` doesnt throw any errors if the user wasnt logged in.
|
注意,即使用户没有登录, ``logout()`` 也不会抛出任何异常。 |
6113天前 |
|
翻译 |
153#翻译 |
In practice, you usually will not need to write your own login/logout functions; the
authentication system comes with a set of views for generically handling logging in
and out.
|
在实际中,你一般不需要自己写登录/登出的函数;认证系统提供了一系例视图用来处理登录和登出。 |
6111天前 |
|
翻译 |
154#翻译 |
The first step in using the authentication views is to wire them up in your URLconf.
Youll need to add this snippet:
|
使用认证视图的第一步是把它们写在你的URLconf中。
你需要这样写: |
6111天前 |
|
翻译 |
157#翻译 |
``/accounts/login/`` and ``/accounts/logout/`` are the default URLs that Django uses
for these views.
|
``/accounts/login/`` 和 ``/accounts/logout/`` 是Django提供的视图的默认URL。 |
6086天前 |
|
翻译 |
158#翻译 |
By default, the ``login`` view renders a template at ``registration/login.html``
(you can change this template name by passing an extra view argument
,``template_name``). This form needs to contain a ``username`` and a ``password``
field. A simple template might look like this:
|
缺省情况下, ``login`` 视图渲染 ``registragiton/login.html`` 模板(可以通过视图的额外参数 ``template_name`` 修改这个模板名称)。这个表单必须包含 ``username`` 和 ``password`` 域。如下示例: |
5958天前 |
|
翻译 |
161#翻译 |
If the user successfully logs in, he or she will be redirected to
``/accounts/profile/`` by default. You can override this by providing a hidden field
called ``next`` with the URL to redirect to after logging in. You can also pass this
value as a ``GET`` parameter to the login view and it will be automatically added to
the context as a variable called ``next`` that you can insert into that hidden
field.
|
如果用户登录成功,缺省会重定向到 ``/accounts/profile`` 。表单中有一个hidden字段叫 ``next`` ,可以用在登录后指定url。也可以把这个值(指定的url)作为 ``GET`` 参数传递给login视图,这个参数会成为Context中名为 ``next`` 的变量,你可以把这个变量设置给表单中对应的隐含字段。 |
5573天前 |
|
翻译 |
162#翻译 |
The logout view works a little differently. By default it renders a template at
``registration/logged_out.html`` (which usually contains a Youve successfully logged
out message). However, you can call the view with an extra argument, ``next_page`` ,
which will instruct the view to redirect after a logout.
|
logout视图有一些不同。缺省的它渲染 ``registration/logged_out.html`` 模板(这个视图一般包含你已经成功退出的信息)。视图中还可以包含一个参数 ``next_page`` 用于退出后重定向。 |
5754天前 |
|
翻译 |
163#翻译 |
Limiting Access to Logged-in Users
''''''''''''''''''''''''''''''''''
|
限制已登录用户的访问
'''''''''''''''''''''''''''''''''' |
6086天前 |
|
翻译 |
164#翻译 |
Of course, the reason were going through all this trouble is so we can limit access
to parts of our site.
|
有很多原因需要控制用户访问站点的某部分。 |
6062天前 |
|
翻译 |
165#翻译 |
The simple, raw way to limit access to pages is to check
``request.user.is_authenticated()`` and redirect to a login page:
|
一个简单原始的限制方法是检查 ``request.user.is_authenticated()`` ,然后重定向到登陆页面: |
5963天前 |
|
翻译 |
168#翻译 |
or perhaps display an error message:
|
或者显示一个出错信息: |
5981天前 |
|
翻译 |
171#翻译 |
As a shortcut, you can use the convenient ``login_required`` decorator:
|
作为一个快捷方式, 你可以使用便捷的 ``login_required`` 修饰符: |
6086天前 |
|
翻译 |
174#翻译 |
``login_required`` does the following:
|
``login_required`` 做下面的事情: |
6086天前 |
|
翻译 |
175#翻译 |
* If the user isnt logged in, redirect to ``/accounts/login/`` , passing the
current absolute URL in the query string as ``next`` , for example:
``/accounts/login/?next=/polls/3/`` .
|
* 如果用户没有登录, 重定向到 ``/accounts/login/`` , 把当前绝对URL作为 ``next`` 在查询字符串中传递过去, 例如:
``/accounts/login/?next=/polls/3/`` .
|
6086天前 |
|
翻译 |
176#翻译 |
* If the user is logged in, execute the view normally. The view code can then
assume that the user is logged in.
|
* 如果用户已经登录, 正常地执行视图函数. 视图代码就可以假定用户已经登录了. |
6086天前 |
|
翻译 |
177#翻译 |
Limiting Access to Users Who Pass a Test
''''''''''''''''''''''''''''''''''''''''
|
对通过测试的用户限制访问 |
6062天前 |
|
翻译 |
178#翻译 |
Limiting access based on certain permissions or some other test, or providing a
different location for the login view works essentially the same way.
|
限制访问可以基于某种权限,某些检查或者为login视图提供不同的位置,这些实现方式大致相同 |
6062天前 |
|
翻译 |
179#翻译 |
The raw way is to run your test on ``request.user`` in the view directly. For
example, this view checks to make sure the user is logged in and has the permission
``polls.can_vote`` (more about how permissions works follows):
|
一般的方法是直接在视图的 ``request.user`` 上运行检查。例如,下面视图检查用户登陆并是否有 ``polls.can_vote`` 的权限: |
5958天前 |
|
翻译 |
182#翻译 |
Again, Django provides a shortcut called ``user_passes_test`` . It takes arguments
and generates a specialized decorator for your particular situation:
|
并且Django有一个称为 ``user_passes_test`` 的简洁方式。它根据情况使用参数并且产生特殊装饰符。 |
5958天前 |
|
翻译 |
185#翻译 |
``user_passes_test`` takes one required argument: a callable that takes a ``User``
object and returns ``True`` if the user is allowed to view the page. Note that
``user_passes_test`` does not automatically check that the ``User`` is
authenticated; you should do that yourself.
|
``user_passes_test`` 使用一个必需的参数:一个可调用的方法,当存在 ``User`` 对象并当此用户允许查看该页面时返回 ``True`` 。
注意 ``user_passes_test`` 不会自动检查 ``User`` 是否认证,你应该自己做这件事。 |
5653天前 |
|
翻译 |
186#翻译 |
In this example were also showing the second optional argument, ``login_url`` ,
which lets you specify the URL for your login page (``/accounts/login/`` by
default).
|
例子中我们也展示了第二个可选的参数 ``login_url`` ,它让你指定你的登录页面的URL(默认为 ``/accounts/login/`` )。 |
5958天前 |
|
翻译 |
187#翻译 |
Since its a relatively common task to check whether a user has a particular
permission, Django provides a shortcut for that case: the ``permission_required()``
decorator. Using this decorator, the earlier example can be written as follows:
|
既然检查用户是否有一个特殊权限是相对常见的任务,Django为这种情形提供了一个捷径: ``permission_required()`` 装饰器
使用这个装饰器,前面的例子可以这样写: |
5958天前 |
|
翻译 |
190#翻译 |
Note that ``permission_required()`` also takes an optional ``login_url`` parameter,
which also defaults to ``'/accounts/login/'`` .
|
注意, ``permission_required()`` 也有一个可选的 ``login_url`` 参数, 这个参数默认为 ``'/accounts/login/'`` 。 |
5958天前 |
|
翻译 |
191#翻译 |
Limiting Access to Generic Views
|
限制通用视图的访问 |
6086天前 |
|
翻译 |
192#翻译 |
One of the most frequently asked questions on the Django users list deals with
limiting access to a generic view. To pull this off, youll need to write a thin
wrapper around the view and point your URLconf to your wrapper instead of the
generic view itself:
|
在Django用户邮件列表中问到最多的问题是关于对通用视图的限制性访问。为实现这个功能,你需要自己包装视图,并且在URLconf中,将你自己的版本替换通用视图: |
5958天前 |
|
翻译 |
195#翻译 |
You can, of course, replace ``login_required`` with any of the other limiting
decorators.
|
当然, 你可以用任何其他限定修饰符来替换 ``login_required`` 。 |
5958天前 |
|
翻译 |
196#翻译 |
Managing Users, Permissions, and Groups
'''''''''''''''''''''''''''''''''''''''
|
管理 Users, Permissions 和 Groups
''''''''''''''''''''''''''''''''''''''' |
6112天前 |
|
翻译 |
197#翻译 |
The easiest way by far to manage the auth system is through the admin interface.
Chapter 6 discusses how to use Djangos admin interface to edit users and control
their permissions and access, and most of the time youll just use that interface.
|
管理认证系统最简单的方法是通过管理界面。
第六章讨论了怎样使用Django的管理界面来编辑用户和控制他们的权限和可访问性,并且大多数时间你都会只使用这个界面。 |
6091天前 |
|
翻译 |
198#翻译 |
However, there are low-level APIs you can delve into when you need absolute control,
and we discuss these in the sections that follow.
|
然而,当你需要绝对的控制权的时候,有一些低层 API 需要深入专研,我们将在下面的章节中讨论它们。 |
5958天前 |
|
翻译 |
199#翻译 |
Creating Users
..............
|
创建用户
.............. |
6086天前 |
|
翻译 |
200#翻译 |
Create users with the ``create_user`` helper function:
|
使用 ``create_user`` 辅助函数创建用户: |
6086天前 |
|
翻译 |
203#翻译 |
At this point, ``user`` is a ``User`` instance ready to be saved to the database
(``create_user()`` doesnt actually call ``save()`` itself). You can continue to
change its attributes before saving, too:
|
在这里, ``user`` 是 ``User`` 类的一个实例,准备用于向数据库中存储数据。 ``create_user()`` 函数并没有在数据库中创建记录,在保存数据之前,你仍然可以继续修改它的属性值。 |
5958天前 |
|
翻译 |
206#翻译 |
Changing Passwords
..................
|
修改密码
.................. |
6092天前 |
|
翻译 |
207#翻译 |
You can change a password with ``set_password()`` :
|
你可以使用 ``set_password()`` 来修改密码: |
5958天前 |
|
翻译 |
210#翻译 |
Dont set the ``password`` attribute directly unless you know what youre doing. The
password is actually stored as a *salted hash* and thus cant be edited directly.
|
除非你清楚的知道自己在做什么,否则不要直接修改 ``password`` 属性。其中保存的是密码的 *加入salt的hash值* ,所以不能直接编辑。 |
5958天前 |
|
翻译 |
211#翻译 |
More formally, the ``password`` attribute of a ``User`` object is a string in this
format:
|
一般来说, ``User`` 对象的 ``password`` 属性是一个字符串,格式如下: |
5958天前 |
|
翻译 |
214#翻译 |
Thats a hash type, the salt, and the hash itself, separated by the dollar sign ($)
character.
|
这是哈希类型,salt和哈希本身,用美元符号($)分隔。 |
5958天前 |
|
翻译 |
215#翻译 |
``hashtype`` is either ``sha1`` (default) or ``md5`` , the algorithm used to perform
a one-way hash of the password. ``salt`` is a random string used to salt the raw
password to create the hash, for example:
|
``hashtype`` 是 ``sha1`` (默认)或者 ``md5`` ,它是用来处理单向密码哈希的算法,Salt是一个用来加密原始密码来创建哈希的随机字符串,例如: |
5958天前 |
|
翻译 |
218#翻译 |
The ``User.set_password()`` and ``User.check_password()`` functions handle the
setting and checking of these values behind the scenes.
|
``User.set_password()`` 和 ``User.check_password()`` 函数在后台处理和检查这些值。 |
5958天前 |
|
翻译 |
219#翻译 |
Is a Salted Hash Some Kind of Drug?
|
一个加入salt的哈希算法是某种毒品吗? |
5958天前 |
|
翻译 |
220#翻译 |
No, a *salted hash* has nothing to do with marijuana; its actually a common way to
securely store passwords. A *hash* is a one-way cryptographic functionthat is, you
can easily compute the hash of a given value, but its nearly impossible to take a
hash and reconstruct the original value.
|
不是,一个 *加入salt值的哈希算法* 可不是什么毒品;事实上它是一种确保密码存储安全的常用方法。一次 *哈希* 是一次单向的加密过程,你能容易地计算出一个给定值的哈希码,但是几乎不可能从一个哈希码解出它的原值。 |
5573天前 |
|
翻译 |
221#翻译 |
If we stored passwords as plain text, anyone who got their hands on the password
database would instantly know everyones password. Storing passwords as hashes
reduces the value of a compromised database.
|
如果我们以普通文本存储密码,任何能进入数据库的人都能轻易的获取每个人的密码。使用哈希方式来存储密码相应的减少了数据库泄露密码的可能。 |
5962天前 |
|
翻译 |
222#翻译 |
However, an attacker with the password database could still run a *brute- force*
attack, hashing millions of passwords and comparing those hashes against the stored
values. This takes some time, but less than you might thinkcomputers are incredibly
fast.
|
然而,攻击者仍然可以使用 *暴力破解* 使用上百万个密码与存储的值对比来获取数据库密码,这需要花一些时间,但是智能电脑惊人的速度超出了你的想象 |
5958天前 |
|
翻译 |
223#翻译 |
Worse, there are publicly available *rainbow tables* , or databases of precomputed
hashes of millions of passwords. With a rainbow table, an attacker can break most
passwords in seconds.
|
更糟糕的是我们可以公开地得到 *rainbow tables* (一种暴力密码破解表)或预备有上百万哈希密码值的数据库。使用rainbow tables可以在几秒之内就能搞定最复杂的一个密码。 |
5958天前 |
|
翻译 |
224#翻译 |
Adding a *salt* basically an initial random valueto the stored hash adds another
layer of difficulty to breaking passwords. Since salts differ from password to
password, they also prevent the use of a rainbow table, thus forcing attackers to
fall back on a brute-force attack, itself made more difficult by the extra entropy
added to the hash by the salt.
|
在存储的hash值的基础上,加入 *salt* 值(一个随机值),增加了密码的强度,使得破解更加困难。因为每个密码的salt值都不相同,这也限制了rainbow table的使用,使得攻击者只能使用最原始的暴力破解方法。而加入的salt值使得hash的熵进一步获得增加,使得暴力破解的难度又进一步加大。 |
5958天前 |
|
翻译 |
225#翻译 |
While salted hashes arent absolutely the most secure way of storing passwords,
theyre a good middle ground between security and convenience.
|
加入salt值得hash并不是绝对安全的存储密码的方法,然而在安全和方便之间有很大的中间地带需要我们来做决定。 |
5958天前 |
|
翻译 |
226#翻译 |
Handling Registration
.....................
|
处理注册 |
6003天前 |
|
翻译 |
227#翻译 |
We can use these low-level tools to create views that allow users to sign up. Nearly
every developer wants to implement registration differently, so Django leaves
writing a registration view up to you. Luckily, its pretty easy.
|
我们可以使用这些底层工具来创建允许用户注册的视图。最近每个开发人员都希望实现各自不同的注册方法,所以Django把写一个注册视图的工作留给了你。幸运的是,这很容易。 |
5653天前 |
|
翻译 |
228#翻译 |
At its simplest, we could provide a small view that prompts for the required user
information and creates those users. Django provides a built-in form you can use for
this purpose, which well use in this example:
|
作为这个事情的最简化处理, 我们可以提供一个小视图, 提示一些必须的用户信息并创建这些用户.
Django为此提供了可用的内置表单, 在下面这个例子中很好地使用了: |
5958天前 |
|
翻译 |
231#翻译 |
This form assumes a template named ``registration/register.html`` . Heres an example
of what that template might look like:
|
这个表单构想了一个叫 ``registration/register.html`` 的模板. 这里是一个这个模板的可能的样子的例子: |
5958天前 |
|
翻译 |
234#翻译 |
Note
|
备注 |
6086天前 |
|
翻译 |
235#翻译 |
``django.contrib.auth.forms.UserCreationForm`` is, at the time of publication, an
*oldforms* Form. See `http://www.djangoproject.com/documentation/0.96/forms/`_ for
details on oldforms. The transition to newforms, as covered in Chapter 7, will be
completed in the near future.
|
在本书出版之时, ``django.contrib.auth.forms.UserCreationForm`` 是一个 *oldforms* 表单.
参看 `http://www.djangoproject.com/documentation/0.96/forms/`_ 可以获取有关 oldforms 的详细信息. 转换到有关 newforms 的内容在第7章中将会讲述, newforms 功能
将会在不远的将来完成. |
5958天前 |
|
翻译 |
236#翻译 |
Using Authentication Data in Templates
''''''''''''''''''''''''''''''''''''''
|
在模板中使用认证数据
''''''''''''''''''''''''''''''''''''''
|
5958天前 |
|
翻译 |
237#翻译 |
The current logged-in user and his or her permissions are made available in the
template context when you use ``RequestContext`` (see Chapter 10).
|
当前登入的用户以及他(她)的权限可以通过 ``RequestContext`` 在模板的context中使用(详见第10章)。 |
5958天前 |
|
翻译 |
238#翻译 |
Note
|
备注 |
5958天前 |
|
翻译 |
239#翻译 |
Technically, these variables are only made available in the template context if you
use ``RequestContext`` *and* your ``TEMPLATE_CONTEXT_PROCESSORS`` setting contains
``"django.core.context_processors.auth"`` , which is the default. Again, see Chapter
10 for more information.
|
从技术上来说,只有当你使用了 ``RequestContext`` *并且* ``TEMPLATE_CONTEXT_PROCESSORS`` 设置包含了 ``"django.core.context_processors.auth"`` (默认情况就是如此)时,这些变量才能在模板context中使用。更详细的内容,也请参考第10章。 |
5958天前 |
|
翻译 |
240#翻译 |
When using ``RequestContext`` , the current user (either a ``User`` instance or an
``AnonymousUser`` instance) is stored in the template variable ``{{ user }}`` :
|
当使用 ``RequestContext`` 时, 当前用户 (是一个 ``User`` 实例或一个
``AnonymousUser`` 实例) 存储在模板变量 ``{{ user }}`` 中: |
5958天前 |
|
翻译 |
243#翻译 |
This users permissions are stored in the template variable ``{{ perms }}`` . This is
a template-friendly proxy to a couple of permission methods described shortly.
|
这些用户的权限信息存储在 ``{{ perms }}`` 模板变量中。这是一个在模板中使用很方便的代理,其中包含一些权限相关函数的简写。 |
5958天前 |
|
翻译 |
244#翻译 |
There are two ways you can use this ``perms`` object. You can use something like
``{{ perms.polls }}`` to check if the user has *any* permissions for some given
application, or you can use something like ``{{ perms.polls.can_vote }}`` to check
if the user has a specific permission.
|
你有两种方式来使用 ``perms`` 对象。你可以使用类似于 ``{{ perms.polls }}`` 的形式来检查,对于某个特定的应用,一个用户是否具有 *任意* 权限;你也可以使用 ``{{ perms.polls.can_vote }}`` 这样的形式,来检查一个用户是否拥有特定的权限。 |
5958天前 |
|
翻译 |
245#翻译 |
Thus, you can check permissions in template ``{% if %}`` statements:
|
这样你就可以在模板中的 ``{% if %}`` 语句中检查权限: |
5958天前 |
|
翻译 |
248#翻译 |
The Other Bits: Permissions, Groups, Messages, and Profiles
```````````````````````````````````````````````````````````
|
其他一些功能:权限,组,消息和档案
```````````````````````````````````````````````````````````
|
5958天前 |
|
翻译 |
249#翻译 |
There are a few other bits of the authentication framework that weve only dealt with
in passing. Well take a closer look at them in the following sections.
|
在认证框架中还有其他的一些功能。我们会在接下来的几个部分中进一步地了解它们。 |
5958天前 |
|
翻译 |
250#翻译 |
Permissions
'''''''''''
|
权限
'''''''''''
|
5958天前 |
|
翻译 |
251#翻译 |
Permissions are a simple way to mark users and groups as being able to perform some
action. They are usually used by the Django admin site, but you can easily use them
in your own code.
|
权限可以很方便地标识用户和用户组可以执行的操作。它们被Django的admin管理站点所使用,你也可以在你自己的代码中使用它们。 |
5958天前 |
|
翻译 |
252#翻译 |
The Django admin site uses permissions as follows:
|
Django的admin站点如下使用权限: |
5958天前 |
|
翻译 |
253#翻译 |
* Access to view the add form, and add an object is limited to users with the
*add* permission for that type of object.
|
* 只有设置了 *add* 权限的用户才能使用添加表单,添加对象的视图。
|
5958天前 |
|
翻译 |
254#翻译 |
* Access to view the change list, view the change form, and change an object is
limited to users with the *change* permission for that type of object.
|
* 只有设置了 *change* 权限的用户才能使用变更列表,变更表格,变更对象的视图。 |
5958天前 |
|
翻译 |
255#翻译 |
* Access to delete an object is limited to users with the *delete* permission for
that type of object.
|
* 只有设置了 *delete* 权限的用户才能删除一个对象。
|
5958天前 |
|
翻译 |
256#翻译 |
Permissions are set globally per type of object, not per specific object instance.
For example, its possible to say Mary may change news stories, but its not currently
possible to say Mary may change news stories, but only the ones she created herself
or Mary may only change news stories that have a certain status, publication date,
or ID.
|
权限是根据每一个类型的对象而设置的,并不具体到对象的特定实例。例如,我们可以允许Mary改变新故事,但是目前还不允许设置Mary只能改变自己创建的新故事,或者根据给定的状态,出版日期或者ID号来选择权限。 |
5958天前 |
|
翻译 |
257#翻译 |
These three basic permissionsadd, change, and deleteare automatically created for
each Django model that has a ``class Admin`` . Behind the scenes, these permissions
are added to the ``auth_permission`` database table when you run ``manage.py
syncdb`` .
|
这三个基本权限:添加,变更和删除,会被自动添加到所有的Django模型中,只要该模型包含 ``class Admin`` 。当你执行 ``manage.py syncdb`` 的时候,这些就被自动添加到 ``auth_permission`` 数据表中。 |
5653天前 |
|
翻译 |
258#翻译 |
These permissions will be of the form ``"<app>.<action>_<object_name>"`` . That is,
if you have a ``polls`` application with a ``Choice`` model, youll get permissions
named ``"polls.add_choice"`` , ``"polls.change_choice"`` , and
``"polls.delete_choice"`` .
|
权限以 ``"<app>.<action>_<object_name>"`` 的形式出现。如果你有一个 ``polls`` 的应用,包含一个 ``Choice`` 模型,你就有以下三个权限,分别叫做 ``"polls.add_choice"`` , ``"polls.change_choice"`` ,和
``"polls.delete_choice"`` 。
|
5958天前 |
|
翻译 |
259#翻译 |
Note that if your model doesnt have ``class Admin`` set when you run ``syncdb`` ,
the permissions wont be created. If you initialize your database and add ``class
Admin`` to models after the fact, youll need to run ``syncdb`` again to create any
missing permissions for your installed applications.
|
注意,如果当你运行 ``syncdb`` 时,模型中没有包含 ``class Admin`` ,该模型对应的权限就不会被创建。如果你在初始化数据库以后,又在自己的模型中加入了 ``class
Admin`` ,你就需要重新运行 ``syncdb`` 来为应用加入权限。 |
5958天前 |
|
翻译 |
260#翻译 |
You can also create custom permissions for a given model object using the
``permissions`` attribute on ``Meta`` . This example model creates three custom
permissions:
|
你也可以通过设置 ``Meta`` 中的 ``permissions`` 属性,来为给定的模型定制权限。下面的例子创建了三个自定义的权限: |
5958天前 |
|
翻译 |
263#翻译 |
This only creates those extra permissions when you run ``syncdb`` ; its up to you to
check for these permissions in your views.
|
当你运行 ``syncdb`` 时,额外的权限才会被加入;你需要自己在视图中添加权限相关的代码。 |
5958天前 |
|
翻译 |
264#翻译 |
Just like users, permissions are implemented in a Django model that lives in
``django.contrib.auth.models`` . This means that you can use Djangos database API to
interact directly with permissions if you like.
|
就跟用户一样,权限也就是Django模型中的 ``django.contrib.auth.models`` 。因此如果你愿意,你也可以通过Django的数据库API直接操作权限。 |
5958天前 |
|
翻译 |
265#翻译 |
Groups
''''''
|
组
''''''
|
5958天前 |
|
翻译 |
266#翻译 |
Groups are a generic way of categorizing users so you can apply permissions, or some
other label, to those users. A user can belong to any number of groups.
|
组提供了一种通用的方式来让你按照一定的权限规则和其他标签将用户分类。一个用户可以隶属于任何数量的组。 |
5958天前 |
Patty |
翻译 |
267#翻译 |
A user in a group automatically has the permissions granted to that group. For
example, if the group ``Site editors`` has the permission ``can_edit_home_page`` ,
any user in that group will have that permission.
|
在一个组中的用户自动获得了赋予该组的权限。例如, ``Site editors`` 组拥有 ``can_edit_home_page`` 权限,任何在该组中的用户都拥有这个权限。 |
5958天前 |
|
翻译 |
268#翻译 |
Groups are also a convenient way to categorize users to give them some label, or
extended functionality. For example, you could create a group ``'Special users'`` ,
and you could write code that could, say, give those users access to a members-only
portion of your site, or send them members-only email messages.
|
组也可以通过给定一些用户特殊的标记,来扩展功能。例如,你创建了一个 ``'Special users'`` 组,并且允许组中的用户访问站点的一些VIP部分,或者发送VIP的邮件消息。 |
5958天前 |
|
翻译 |
269#翻译 |
Like users, the easiest way to manage groups is through the admin interface.
However, groups are also just Django models that live in
``django.contrib.auth.models`` , so once again you can always use Djangos database
APIs to deal with groups at a low level.
|
和用户管理一样,admin接口是管理组的最简单的方法。然而,组也就是Django模型 ``django.contrib.auth.models`` ,因此你可以使用Django的数据库API,在底层访问这些组。 |
5958天前 |
|
翻译 |
270#翻译 |
Messages
''''''''
|
消息
''''''''
|
5958天前 |
|
翻译 |
271#翻译 |
The message system is a lightweight way to queue messages for given users. A message
is associated with a ``User`` . Theres no concept of expiration or timestamps.
|
消息系统会为给定的用户接收消息。每个消息都和一个 ``User`` 相关联。其中没有超时或者时间戳的概念。 |
5958天前 |
|
翻译 |
272#翻译 |
Messages are used by the Django admin interface after successful actions. For
example, when you create an object, youll notice a The object was created
successfully message at the top of the admin page.
|
在每个成功的操作以后,Django的admin管理接口就会使用消息机制。例如,当你创建了一个对象,你会在admin页面的顶上看到 ``The object was created successfully`` 的消息。 |
5958天前 |
|
翻译 |
273#翻译 |
You can use the same API to queue and display messages in your own application. The
API is simple:
|
你也可以使用相同的API在你自己的应用中排队接收和显示消息。API非常地简单: |
5652天前 |
|
翻译 |
274#翻译 |
* To create a new message, use ``user.message_set.create(message='message_text')``
.
|
* 要创建一条新的消息,使用 ``user.message_set.create(message='message_text')`` 。
|
5958天前 |
|
翻译 |
275#翻译 |
* To retrieve/delete messages, use ``user.get_and_delete_messages()`` , which
returns a list of ``Message`` objects in the users queue (if any) and deletes
the messages from the queue.
|
* 要获得/删除消息,使用 ``user.get_and_delete_messages()`` ,这会返回一个 ``Message`` 对象的列表,并且从队列中删除返回的项。 |
5958天前 |
|
翻译 |
276#翻译 |
In this example view, the system saves a message for the user after creating a
playlist:
|
在例子视图中,系统在创建了播放单(playlist)以后,为用户保存了一条消息。 |
5958天前 |
|
翻译 |
279#翻译 |
When you use ``RequestContext`` , the current logged-in user and his or her messages
are made available in the template context as the template variable ``{{ messages
}}`` . Heres an example of template code that displays messages:
|
当使用 ``RequestContext`` ,当前登录的用户以及他(她)的消息,就会以模板变量 ``{{ messages }}`` 出现在模板的context中。下面是显示消息的一个例子模板代码: |
5958天前 |
|
翻译 |
282#翻译 |
Note that ``RequestContext`` calls ``get_and_delete_messages`` behind the scenes, so
any messages will be deleted even if you dont display them.
|
需要注意的是 ``RequestContext`` 会在后台调用 ``get_and_delete_messages`` ,因此即使你没有显示它们,它们也会被删除掉。 |
5958天前 |
|
翻译 |
283#翻译 |
Finally, note that this messages framework only works with users in the user
database. To send messages to anonymous users, use the session framework directly.
|
最后注意,这个消息框架只能服务于在用户数据库中存在的用户。如果要向匿名用户发送消息,请直接使用会话框架。 |
5958天前 |
|
翻译 |
284#翻译 |
Profiles
''''''''
|
档案
''''''''
|
5958天前 |
|
翻译 |
285#翻译 |
The final piece of the puzzle is the profile system. To understand what profiles are
all about, lets first look at the problem.
|
最后一个难题是档案系统.为了理解什么是档案,让我们先看看问题.
|
6089天前 |
|
翻译 |
286#翻译 |
In a nutshell, many sites need to store more user information than is available on
the standard ``User`` object. To compound the problem, most sites will have
different extra fields. Thus, Django provides a lightweight way of defining a
profile object thats linked to a given user. This profile object can differ from
project to project, and it can even handle different profiles for different sites
served from the same database.
|
简单来说,许多网站需要存储比标准 ``User`` 对象更多的用户信息。为了解决这个问题,大多数网站都会有不同的额外字段。所以,Django提供一个轻量级的方式定义档案对象链接到指定的用户。这个档案对象在每个项目中可以是不同的,甚至可以为同一数据库服务的不同的站点处理不同的档案。 |
5958天前 |
|
翻译 |
287#翻译 |
The first step in creating a profile is to define a model that holds the profile
information. The only requirement Django places on this model is that it have a
unique ``ForeignKey`` to the ``User`` model; this field must be named ``user`` .
Other that that, you can use any other fields you like. Heres a strictly arbitrary
profile model:
|
创建档案的第一步是定义一个模型(model)来存储档案信息。Django对这个模型所做的唯一的限制是,必须要包含唯一的一个对 ``User`` 模型的 ``ForeignKey`` ,而且这个字段必须要叫做 ``user`` 。其他的字段可以由你自己掌控。下面是一个档案模型的例子: |
5958天前 |
|
翻译 |
290#翻译 |
Next, youll need to tell Django where to look for this profile object. You do that
by setting the ``AUTH_PROFILE_MODULE`` setting to the identifier for your model. So,
if your model lives in an application called ``myapp`` , youd put this in your
settings file:
|
下一步,你需要告诉Django去哪里查找档案对象。你可以通过设置模型中的 ``AUTH_PROFILE_MODULE`` 变量达到这个目的。因此,如果你的模型包含在 ``myapp`` 这个应用中,你就需要如下编写你的设置文件: |
5958天前 |
|
翻译 |
293#翻译 |
Once thats done, you can access a users profile by calling ``user.get_profile()`` .
This function could raise a ``SiteProfileNotAvailable`` exception if
``AUTH_PROFILE_MODULE`` isnt defined, or it could raise a ``DoesNotExist`` exception
if the user doesnt have a profile already (youll usually catch that exception and
create a new profile at that time).
|
一旦完成,你就可以通过调用 ``user.get_profile()`` 函数来获得用户档案。如果 ``AUTH_PROFILE_MODULE`` 变量没有设置,这个函数可能会抛出 ``SiteProfileNotAvailable`` 异常;如果这个用户不存在档案,也可能会抛出 ``DoesNotExist`` 异常(通常情况下,你会捕获这个异常并在当时创建一个新的档案)。 |
5958天前 |
|
翻译 |
294#翻译 |
Whats Next
``````````
|
接下来?
```````` |
5933天前 |
|
翻译 |
295#翻译 |
Yes, the session and authorization system is a lot to absorb. Most of the time you
wont need all the features described in this chapter, but when you need to allow
complex interactions between users, its good to have all that power available.
|
是的,会话和认证系统有太多的东西要学。大多数情况下,你并不需要本章所提到的所有功能。然而当你需要允许用户之间复杂的互操作时,所有的功能都能使用就显得很重要了。 |
5958天前 |
|
翻译 |
296#翻译 |
In the next chapter, well take a look at a piece of Django that builds on top of
this session/user system: the comments application. It allows you to easily attach
commentsfrom anonymous or authenticated usersto arbitrary objects. Onward and
upward!
|
在下一章节中,我们会来深入了解Django建立在会话/用户系统之上的一个系统:评论应用。它允许你很方便地以匿名用户或者注册用户的身份,向任意类型的对象添加评论。让我们继续向前吧。 |
5958天前 |
|
翻译 |