>  기사  >  백엔드 개발  >  Django는 기존 데이터베이스와 애플리케이션을 통합합니다.

Django는 기존 데이터베이스와 애플리케이션을 통합합니다.

黄舟
黄舟원래의
2017-01-17 14:01:041341검색

Django는 아직 잔디가 자라고 있는 미개척지에 처음부터 건물을 짓는 것처럼 처음부터 프로젝트인 소위 그린필드 개발에 가장 적합합니다. 그러나 처음부터 프로젝트를 진행하는 Django의 선호에도 불구하고 프레임워크를 이전 레거시 데이터베이스 및 애플리케이션과 통합하는 것은 여전히 ​​가능합니다. 이 장에서는 몇 가지 통합 기술을 소개합니다.


레거시 데이터베이스와의 통합

Django의 데이터베이스 계층은 Python 코드에서 SQL
스키마를 생성합니다. 그러나 레거시 데이터베이스에는 이미 SQL 스키마가 있습니다. 다음으로 기존 데이터베이스 테이블에 대한 모델을 작성해야 합니다. (성능상의 이유로 Django의 데이터베이스 계층은 데이터베이스의 런타임 검사를 통해 작동하지 않는 객체 관계형 매핑을 지원하지 않습니다. 데이터베이스 API를 사용하려면 모델을 작성해야 합니다. code) 다행히 Django에는 데이터베이스 테이블 계획을 읽어 모델 코드를 생성하는 도우미 도구가 함께 제공됩니다. 이 도우미 도구는 prepare.py
inspectdb


inspectdb 사용

inspectdb 도구는 구성 파일(설정 파일)이 가리키는 데이터베이스를 내부적으로 검사하고, 각 테이블에 대해 Django

모델 표현을 생성한 다음 이러한 Python 모델의 코드를 표준 출력에 표시합니다. 시스템 안으로.


다음은 일반적인 레거시 데이터베이스를 처음부터 통합하는 과정입니다.


django-admin .py를 실행하여 startproject mysite(여기서 mysite는 프로젝트 이름)는 Django 프로젝트를 생성합니다. 좋습니다. 이 예에서는 프로젝트 이름으로 mysite를 사용하겠습니다.


프로젝트

mysite/settings.py에서 구성 파일을 편집하고 Django에 데이터베이스 연결 매개변수와 데이터베이스 이름을 알려주세요. 특히, pythonmysite/manage.pystartappmyapp(여기서 myapp은 애플리케이션 이름임)을 실행하여 DATABASE_NAME, DATABASE_ENGINE, DATABASE_USER, DATABASE_PASSWORD, DATABASE_HOST 및 DATABASE_PORT 구성 정보를 제공합니다. Django 애플리케이션을 생성합니다. 그런 다음 myapp을 애플리케이션 이름으로 사용합니다.

pythonmysite/manage.pyinspectdb 명령을 실행합니다. 모두 확인하세요. 테이블을 출력하고 각 테이블에 대해 생성된 모델
클래스를 인쇄합니다. 출력을 살펴보고 Inspectiondb가 무엇을 할 수 있는지 생각해 보세요.


표준을 변환하여 출력을 리디렉션합니다. 셸을 실행하고 애플리케이션의 models.py 파일에 출력을 저장합니다.

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

mysite/myapp/ 편집 models.py 파일을 사용하여 생성된 모델을 정리하고 필요한 사용자 정의를 수행합니다. 다음 장에는 이에 대한 좋은 조언이 있습니다.


생성된 모델 정리

예상할 수 있듯이 데이터베이스 자체 검사는 완벽하지 않으며 생성된 모델 코드를 일부 정리해야 합니다. 생성된 모델 처리에 대한 몇 가지 중요한 사항은 다음과 같습니다.


데이터베이스의 각 테이블은 모델 클래스(즉, 데이터베이스 테이블과 모델 클래스)로 변환됩니다. 사이의 일대일 매핑). 이는 다대다 조인을 위해 모델이 ManyToManyField 개체인 테이블을 리팩터링해야 함을 의미합니다.

생성된 각 모델의 각 필드에는 ID 기본 키 필드를 포함하여 고유한 속성이 있습니다. 그러나 모델에 기본 키가 없으면 Django는 자동으로 Id 기본 키 필드를 모델에 추가합니다. 이 경우 다음 코드를 사용하여 행을 삭제할 수 있습니다. 애플리케이션이 이러한 테이블에 새 레코드를 추가해야 하는 경우 이러한 행은 문제를 일으킬 수 있습니다. Inspectiondb 명령으로는 필드가 자동 증가하는지 감지할 수 없으므로 필요한 경우 AutoField로 수정해야 합니다.

CharField, DateField 등 각 필드 유형이 결정됩니다. VARCHAR 및 DATE와 같은 데이터베이스 열 유형을 찾아보세요. Inspectiondb가 특정 모델 필드 유형을 데이터베이스 열 유형에 매핑할 수 없는 경우 대신 TextField 필드를 사용하고 생성된 모델 필드 뒤에 "이 필드 유형은 추측됩니다"라는 Python 주석을 추가합니다. 따라서 이에 특별한 주의를 기울이고 필요한 경우 해당 필드 유형을 적절하게 수정하십시오.

Django에서 데이터베이스의 필드가 적절한 대응 항목을 찾을 수 없는 경우 Django 레이어에서는 이를 요구하지 않으므로 안전하게 건너뛸 수 있습니다. 테이블의 모든 필드를 포함합니다.


데이터베이스의 열 이름이 pass, class 또는 for 등 Python의 예약어인 경우,spectdb는 각 속성 이름 뒤에 _field를 추가합니다. 그리고 db_column 속성을 pass, class 또는 for 등과 같은 실제 필드 이름으로 설정합니다.


예를 들어 테이블에 열 이름이 for인 INT 유형 열이 포함된 경우 생성된 모델에는 아래와 같은 필드가 포함됩니다.

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

inspectdb는 필드 뒤에 'Python 예약어이므로 필드 이름 바꾸기'를 추가합니다.

如果数据库中某张表引用了其他表(正如大多数数据库系统所做的那样),你需要适当的修改所生成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。


与认证系统的整合


将Django与其他现有认证系统的用户名和密码或者认证方法进行整合是可以办到的。


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


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


指定认证后台


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


认证后台列表在AUTHENTICATION_BACKENDS设置中进行指定,它应该是指向知道如何认证的Python类的Python路径的名字数组,这些类可以放置在您的Python路径的任何位置上。


默认情况下,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。


如Django会话、用户和注册中所述,Django管理系统紧密连接于其自己后台数据库的User对象。实现这个功能的最好办法就是为您的后台数据库(如LDAP目录,外部SQL数据库等)中的每个用户都创建一个对应的Django
User对象。您可以提前写一个脚本来完成这个工作,也可以在某个用户第一次登陆的时候在authenticate方法中进行实现。


以下是一个示例后台程序,该后台用于认证定义在setting.py文件中的username和password变量,并且在该用户第一次认证的时候创建一个相应的DjangoUser对象。

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类型代理至不同的技术。


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

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

这里, a18e6dc59b27f1dbd64eaa88f15b0c14这一行表示用Django处理每个以根开头的URL.


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

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

有了这样的设置,只有那些以/admin/开头的URL地址才会触发Django去进行处理,而任何其他页面依旧按之前已经存在的那些设置进行处理。


请注意,让Diango去处理那些合格的URL(比如在本章例子中的/admin/)并不会影响其对URL的解析。绝对路径对Django才是有效的(例如/admin/people/person/add/),而非去掉/admin/后的那部分URL(例如``/people/person/add/)。这意味着您的根URLconf必须包含居前的/admin/。

以上就是Django集成已有的数据库和应用的内容,更多相关内容请关注PHP中文网(www.php.cn)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.