web.py에서 Django의 ORM과 유사한 조회 효과 구현
Django 프레임워크는 ORM을 자체로 가지고 비교적 강력하고 편리한 조회 기능을 실현했는데 이런 기능들은 표와 무관하다.예를 들면 다음과 같습니다.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
Question.objects.all()Question.objects.get(pk=1)
예를 들어 알 수 있듯이
objects.all
와 objects.get
이런 기능들은 모두 class Question
에서 정의된 것이 아니라 부류models.Model
에서 정의된 것일 수도 있고 아닐 수도 있다.그럼 저희는 웹에서.py에서 어떻게 이런 기능을 실현합니까?(만약 당신이 SQLAlchemy를 선택한다면 스스로 실현할 필요가 없다).이루어지다
사고의 방향
우리는
Question.objects.all()
이러한 호출은 클래스 속성objects
에 직접 접근하고 objects
속성을 호출하는 방법all()
을 발견했다.여기objects
는 실례일 수도 있고 종류일 수도 있다.저는 개인적으로 (저는 Django의 실현을 본 적이 없습니다) 이것은 실례가 되어야 한다고 생각합니다. 실례화된 과정은 표의 정보를 전달할 수 있기 때문에 유사all()
와 같은 함수가 작동할 수 있기 때문입니다.분석을 거친 후에 우리는 우리가 해결해야 할 문제를 열거할 수 있다.Model
를 실현해야 한다. 실제 표는 이 부류로부터 자신이 정의하지 않은 기능을 계승할 수 있다.objects.all()
와 같은 조회 효과를 갖추어야 한다.위의 수요를 통해 알 수 있듯이 우리는 클래스가 정의될 때 이러한 기능을 실현해야 한다. 클래스가 실례화될 때까지 기다렸다가 이런 기능을 실현해야 한다.클래스 정의를 할 때 기능을 실현합니까?메타클래스가 하는 일이잖아.따라서 실현 과정은 다음과 같다.
Model
류를 실현하는데 그 귀속 방법은 표의 증가, 삭제, 수정과 관련이 있다.Model
류의 원류는 ModelMetaClass
이고 이 원류의 정의 과정에서 클래스에 objects
대상을 추가했다. 이 대상은 ModelDefaultManager
류의 실례로 표의 조회 기능을 실현했다.코드
코드를 안 주면 깡패라니까 내가 줄게.설명: 사용하는 데이터베이스 조작은 모두 웹입니다.py의db 라이브러리의 인터페이스입니다.
# -*- coding: utf-8 -*-
import web
import config # ,
def _connect_to_db():
return web.database(dbn="sqlite", db=config.dbname)
def init_db():
db = _connect_to_db()
for statement in config.sql_statements:
db.query(statement)
class ModelError(Exception):
"""Exception raised by all models.
Attributes:
msg: Error message.
"""
def __init__(self, msg=""):
self.msg = msg
def __str__(self):
return "ModelError: %s" % self.msg
class ModelDefaultManager(object):
"""ModelManager implements query functions against a model.
Attributes:
cls: The class to be managed.
"""
def __init__(self, cls):
self.cls = cls
self._table_name = cls.__name__.lower()
def all(self):
db = _connect_to_db()
results = db.select(self._table_name)
return [self.cls(x) for x in results]
def get(self, query_vars, where):
results = self.filter(query_vars, where, limit=1)
if len(results) > 0:
return results[0]
else:
return None
def filter(self, query_vars, where, limit=None):
db = _connect_to_db()
try:
results = db.select(self._table_name, vars=query_vars, where=where,
limit=limit)
except (Exception) as e:
raise ModelError(str(e))
return [self.cls(x) for x in results]
class ModelMetaClass(type):
def __new__(cls, classname, bases, attrs):
new_class = super(ModelMetaClass, cls).__new__(cls, classname,
bases, attrs)
objects = ModelDefaultManager(new_class)
setattr(new_class, "objects", objects)
return new_class
class Model(object):
"""Parent class of all models.
"""
__metaclass__ = ModelMetaClass
def __init__(self):
pass
def _table_name(self):
return self.__class__.__name__.lower()
def insert(self, **kargs):
db = _connect_to_db()
try:
with db.transaction():
db.insert(self._table_name(), **kargs)
except (Exception) as e:
raise ModelError(str(e))
def delete(self, where, using=None, vars=None):
db = _connect_to_db()
try:
with db.transaction():
db.delete(self._table_name(), where, vars=vars)
except (Exception) as e:
raise ModelError(str(e))
def save(self, where, vars=None, **kargs):
db = _connect_to_db()
try:
with db.transaction():
db.update(self._table_name(), where, vars, **kargs)
except (Exception) as e:
raise ModelError(str(e))
사용
먼저 테이블에 해당하는 클래스를 정의합니다.
class Users(Model):
...
다음과 같이 Django를 사용합니다.
user_list = Users.objects.all()
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.