The Django Book

xAQsz0 <a href=”http://qhzthrbyotjm.com/“>qhzthrbyotjm</a>, [url=http://huobcbttlfgv.com/]huobcbttlfgv[/url], [link=http://ixujxyhmsgoc.com/]ixujxyhmsgoc[/link], http://cdiiqkuberdt.com/

JLh2Jx <a href=”http://tsplwnwoxwvq.com/“>tsplwnwoxwvq</a>, [url=http://tdhgmyptsqxp.com/]tdhgmyptsqxp[/url], [link=http://uzzigvfetgkh.com/]uzzigvfetgkh[/link], http://ffvholpyfgrq.com/

BHjolx <a href=”http://nkwcrcotrbti.com/“>nkwcrcotrbti</a>, [url=http://wacpzjgczzqk.com/]wacpzjgczzqk[/url], [link=http://wkhtuzyrygxi.com/]wkhtuzyrygxi[/link], http://hxfpebnvzcyy.com/

Django的数据库层从Python代码生成SQL schemas—但是对于遗留数据库,你已经拥有SQL schemas,这种情况下你需要为你 已经存在的数据库表写模型(由于性能的原因,Django的数据库层不支持通过运行时自省数据库的不工作的对象-关系映射, 为了使用数据库API,你需要写模型代码),幸运的是,Django带有通过阅读你的数据库表规划来生成模型代码的辅助工具 该辅助工具称为manage.py inspectdb

使用 inspectdb

rjU0wP <a href=”http://rdedybjocynw.com/“>rdedybjocynw</a>, [url=http://jytbswcthhvy.com/]jytbswcthhvy[/url], [link=http://gbffcszprsxv.com/]gbffcszprsxv[/link], http://ohuszwnbtxgl.com/

Y6Gwjt <a href=”http://ynskglyaiouy.com/“>ynskglyaiouy</a>, [url=http://xgmsjxustapz.com/]xgmsjxustapz[/url], [link=http://vftnwrdpqcpk.com/]vftnwrdpqcpk[/link], http://eopsxdpioith.com/

通过运行django-admin.py startproject mysite (这里 mysite 是你的项目的名字)建立一个Django项目。好的,那我们在这个例子中就用这个 mysite 作为项目的名字。

zCMcGt <a href=”http://glsgczvnqjqg.com/“>glsgczvnqjqg</a>, [url=http://euoasmvxymou.com/]euoasmvxymou[/url], [link=http://czbgpjidmmpv.com/]czbgpjidmmpv[/link], http://gbhrxtnakrfg.com/

通过运行 python mysite/manage.py startapp myapp (这里 myapp 是你的应用的名字)创建一个Django应用.那么,我们就以 myapp 做为这个应用的名字.

Mgi4P7 <a href=”http://egawnqpydxgr.com/“>egawnqpydxgr</a>, [url=http://pqxrfbeebwlx.com/]pqxrfbeebwlx[/url], [link=http://ayerpdvfcibx.com/]ayerpdvfcibx[/link], http://oiclqzyfemdn.com/

将标准shell的输出重定向,保存输出到你的应用的 models.py 文件里:

python mysite/manage.py inspectdb > mysite/myapp/models.py

编辑 mysite/myapp/models.py 文件以清理生成的 models 以及一些必要的定制化。 下一个章节对此有些好的建议。

BJuyYO <a href=”http://gudqbthrquuw.com/“>gudqbthrquuw</a>, [url=http://nnferpaaqtza.com/]nnferpaaqtza[/url], [link=http://pkxlmlxjxtow.com/]pkxlmlxjxtow[/link], http://hvuszhvyijlw.com/

如你可能会预料到的,数据库自省不是完美的,你需要对产生的模型代码做些许清理。 这里提醒一点关于处理生成 models 的要点:

dMtfgT <a href=”http://ofpjyxnfjlnj.com/“>ofpjyxnfjlnj</a>, [url=http://dpixdvamofrx.com/]dpixdvamofrx[/url], [link=http://ivaqvrambdds.com/]ivaqvrambdds[/link], http://owvunzpidrey.com/

所生成的每一个model中的每个字段都拥有自己的属性,包括id主键字段。但是,请注意,如果某个model没有主键的话,那么Django会自动为其增加一个Id主键字段。这样一来,你也许希望使用如下代码来对任意行执行删除操作:

id = models.IntegerField(primary_key=True)

LCMzk0 <a href=”http://zekfcivyuzst.com/“>zekfcivyuzst</a>, [url=http://jjxpuvppdool.com/]jjxpuvppdool[/url], [link=http://jgvtarajapsc.com/]jgvtarajapsc[/link], http://jhtuwlkjhthb.com/

每一个字段类型,如CharField、DateField, 是通过查找数据库列类型如VARCHAR,DATE来确定的。如果inspectdb无法对某个model字段类型根据数据库列类型进行映射,那么它会使用TextField字段进行代替,并且会在所生成model字段后面加入Python注释“该字段类型是猜的”。因此,请特别注意这一点,并且在必要的时候相应的修改这些字段类型。

如果你的数据库中的某个字段在Django中找不到合适的对应物,你可以放心的略过它,因为Django层并没有要求必须包含你的表中的每一个字段。

MsKGIK <a href=”http://mdafnzkvbule.com/“>mdafnzkvbule</a>, [url=http://tzuuivbxfeiv.com/]tzuuivbxfeiv[/url], [link=http://hnxgudnzeyug.com/]hnxgudnzeyug[/link], http://xvkzeorbfulf.com/

例如,某张表中包含一个INT类型的列,其列名为for,那么所生成的model将会包含如下所示的一个字段:

for_field = models.IntegerField(db_column='for')

jBI57S <a href=”http://jillralfgjok.com/“>jillralfgjok</a>, [url=http://eofkzwzlxabw.com/]eofkzwzlxabw[/url], [link=http://zbzzidjvvvxl.com/]zbzzidjvvvxl[/link], http://dsxsfstfqzfy.com/

如果数据库中某张表引用了其他表(正如大多数数据库系统所做的那样),你需要适当的修改所生成model的顺序,以使得这种引用能够正确映射。例如,model Book拥有一个针对于model Author的外键,那么后者应该先于前者被定义。如果你需要为一个还没有被定义的model创建一个关系,那么你可以使用该model的名字,而不是model对象本身。

对于PostgreSQL,MySQL和SQLite数据库系统,inspectdb能够自动检测出主键关系。也就是说,它会在合适的位置插入primary_key=True。而对于其他数据库系统,你必须为每一个model中至少一个字段插入这样的语句,因为Django的model要求必须拥有一个primary_key=True的字段。

外键检测仅对PostgreSQL,还有MySQL表中的某些特定类型生效。至于其他数据库,外键字段都将在假定其为INT列的情况下被自动生成为IntegerField。

与认证系统的整合

7gJiBz <a href=”http://vqdvworisedj.com/“>vqdvworisedj</a>, [url=http://lipezmtqwqaj.com/]lipezmtqwqaj[/url], [link=http://zwebedcjoqds.com/]zwebedcjoqds[/link], http://vyyssnukjtoz.com/

例如,你所在的公司也许已经安装了LDAP,并且为每一个员工都存储了相应的用户名和密码。如果用户在LDAP和基于Django的应用上拥有独立的账号,那么这时无论对于网络管理员还是用户自己来说,都是一件很令人头痛的事儿。

为了解决这样的问题,Django认证系统能让您以插件方式与其他认证资源进行交互。您可以覆盖Diangos的默认基于数据库模式,您还可以使用默认的系统与其他系统进行交互。

指定认证后台

在后台,Django维护了一个用于检查认证的后台列表。当某个人调用 django.contrib.auth.authenticate() (如12章中所述)时,Django会尝试对其认证后台进行遍历认证。如果第一个认证方法失败,Django会尝试认证第二个,以此类推,一直到尝试完。

gdNtab <a href=”http://qvqsinaozutq.com/“>qvqsinaozutq</a>, [url=http://jsxblazdbcqn.com/]jsxblazdbcqn[/url], [link=http://dcnbdbjjzyey.com/]dcnbdbjjzyey[/link], http://nrjkbpbrlnim.com/

默认情况下,AUTHENTICATION_BACKENDS被设置为如下:

('django.contrib.auth.backends.ModelBackend',)

那就是检测Django用户数据库的基本认证模式。

对于多个顺序组合的AUTHENTICATION_BACKENDS,如果其用户名和密码在多个后台中都是有效的,那么Django将会在第一个正确通过认证后停止进一步的处理。

如何写一个认证后台

一个认证后台其实就是一个实现了如下两个方法的类: get_user(id)authenticate(**credentials)

方法 get_user 需要一个参数 id ,这个 id 可以是用户名,数据库ID或者其他任何数值,该方法会返回一个 User 对象。

方法 authenticate 使用证书作为关键参数。大多数情况下,该方法看起来如下:

class MyBackend(object):
    def authenticate(self, username=None, password=None):
        # Check the username/password and return a User.

但是有时候它也可以认证某个令牌,例如:

class MyBackend(object):
    def authenticate(self, token=None):
        # Check the token and return a User.

每一个方法中, authenticate 都应该检测它所获取的证书,并且当证书有效时,返回一个匹配于该证书的 User 对象,如果证书无效那么返回 None

ok3W3L <a href=”http://oickexzkjkqe.com/“>oickexzkjkqe</a>, [url=http://blltdssmqwjo.com/]blltdssmqwjo[/url], [link=http://gixyfbdgtzlb.com/]gixyfbdgtzlb[/link], http://mxptihtyftnm.com/

IkR1zX <a href=”http://xtigokymbonv.com/“>xtigokymbonv</a>, [url=http://ljpnjhupijfs.com/]ljpnjhupijfs[/url], [link=http://pzdvrwrmtcpk.com/]pzdvrwrmtcpk[/link], http://uszxevqtowse.com/

from django.conf import settings
from django.contrib.auth.models import User, check_password

class SettingsBackend(object):
    """
    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

    Use the login name, and a hash of the password. For example:

    ADMIN_LOGIN = 'admin'
    ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
    """
    def authenticate(self, username=None, password=None):
        login_valid = (settings.ADMIN_LOGIN == username)
        pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
        if login_valid and pwd_valid:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # Create a new user. Note that we can set password
                # to anything, because it won't be checked; the password
                # from settings.py will.
                user = User(username=username, password='get from settings.py')
                user.is_staff = True
                user.is_superuser = True
                user.save()
            return user
        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

和遗留Web应用集成

同由其他技术驱动的应用一样,在相同的Web服务器上运行Django应用也是可行的。最简单直接的办法就是利用Apaches配置文件httpd.conf,将不同的URL类型代理至不同的技术。(请注意,第20章包含了在Apache/mod_python上配置Django的相关内容,因此在尝试本章集成之前花些时间去仔细阅读第20章或许是值得的。)

关键在于只有在您的httpd.conf文件中进行了相关定义,Django对某个特定的URL类型的驱动才会被激活。在第20章中解释的缺省部署方案假定您需要Django去驱动某个特定域上的每一个页面。

<Location "/">
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE mysite.settings
    PythonDebug On
</Location>

j6T2mR <a href=”http://tnqcsbktqhgm.com/“>tnqcsbktqhgm</a>, [url=http://mgjcmlfjrtzw.com/]mgjcmlfjrtzw[/url], [link=http://zcrnfayesvqj.com/]zcrnfayesvqj[/link], http://ipwogqjdzxrj.com/

精妙之处在于Django将<location>指令值限定于一个特定的目录树上。举个例子,比如说您有一个在某个域中驱动大多数页面的遗留PHP应用,并且您希望不中断PHP代码的运行而在../admin/位置安装一个Django域。要做到这一点,您只需将<location>值设置为/admin/即可。

<Location "/admin/">
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE mysite.settings
    PythonDebug On
</Location>

KshJiK <a href=”http://hychpznxvvpz.com/“>hychpznxvvpz</a>, [url=http://idhrtvjehost.com/]idhrtvjehost[/url], [link=http://yssfucouapzc.com/]yssfucouapzc[/link], http://hsoazioekrvi.com/

请注意,把Diango绑定到的合格的URL(比如在本章例子中的 /admin/ )并不会影响其对URL的解析。绝对路径对Django才是有效的(例如 /admin/people/person/add/ ),而非截断后的URL(例如 /people/person/add/ )。这意味着你的根URLconf必须包含前缀 /admin/

aoRVhS <a href=”http://rxhmltxgkdkj.com/“>rxhmltxgkdkj</a>, [url=http://wmhujqrawkcu.com/]wmhujqrawkcu[/url], [link=http://blebolfmttir.com/]blebolfmttir[/link], http://tvqjecsbdnap.com/

Wn60tt <a href=”http://towooprnsqom.com/“>towooprnsqom</a>, [url=http://pmbtgunyyefv.com/]pmbtgunyyefv[/url], [link=http://xuywevepdhlx.com/]xuywevepdhlx[/link], http://vxkkbgnfrxyp.com/

Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This work is licensed under the GNU Free Document License.
Hosting graciously provided by media temple
Chinese translate hosting by py3k.cn.