在我们的工作场所,我们在同一个网站上同时使用 django 和 flask。这样做的原因是 django 的管理和模型系统非常快速地为其编写代码,并且它充当我们的后端(仅限员工)管理界面。另一方面,在flask中编写前端要容易得多,因为每个页面都可以像一个python函数和一个Jinja2模板一样简单。 Flask 表单需要一个额外的表单模型类(它很容易编写)来指定表单中的所有字段,如果要将表单响应保存到 SQL 数据库,则需要第二个 SQLAlchemy 模型。如果您要在 django 中编写相同的表单,在最简单的情况下,您不需要编写表单模型,因为 django 框架隐式地从 sql 模型生成它。不过,在烧瓶中编写“常规”页面仍然更快。
至于让两者一起玩得很好,它最终的工作方式是我们首先编写 django 模型,因为数据库管理和 sql 模式迁移已融入 django。然后我们使用 SQLAlchemy 的一个称为“反射”的功能,它读取 sql 数据库并从模式中生成 sql 模型。这样,当我们对 django 模型进行更改时,我们运行 manage.py migrate(它将架构更改部署到 sql 数据库),SQLAlchemy 模型会自动反映新架构,而无需我们接触 Flask-SQLAlchemy 模型.这是一个示例,其中包含一些外键内容和一些时间戳,这些内容在您使用 ORM 保存模型时会自动更新。我已经包含了这些,因为它们都是常见的用例,并且都需要额外的代码。
Django 模型:
from django.db import models
class DjangoModel(models.Model):
field1 = models.CharField(max_length=10)
field2 = models.IntegerField()
field3 = models.DateTimeField()
# We frequently use timestamps like this that the ORM updates automatically on creation and modification respectively.
created_timestamp = models.DateTimeField(auto_now_add=True)
modified_timestamp = models.DateTimeField(auto_now=True)
related = models.ForeignKey(SomeOtherDjangoModel, related_name='related_backref')
class Meta:
db_table = 'sql_table_name'
Flask-SQLAlchemy 模型:
from flask import current_app
from flask_sqlalchemy import SQLAlchemy
import datetime
# The next three lines should be in your application.py ideally.
db = SQLAlchemy()
db.init_app(current_app)
db.Model.metadata.reflect(db.engine)
class FlaskSQLAlchemyModel(db.Model):
# All 6 fields from the django model and the implicit 'id' field django
# adds to its models will get reflected automatically the way this model
# is coded. The created_timestamp and modified_timestamp fields require
# special code for Flask-SQLAlchemy to update them automatically when
# you save a model instance. Relationships must be defined manually in
# Flask-SQLAlchemy, so there's code for that, too.
__table__ = db.Table('sql_table_name', db.Model.metadata,
# You'll need to "override" the timestamp fields to get flask-sqlalchemy to update them automatically on creation and modification respectively.
db.Column('created_timestamp', db.DateTime, default=datetime.datetime.now),
db.Column('modified_timestamp', db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now),
autoload=True,
extend_existing=True,
autoload_with=db.engine,
)
# You need to do model relationships manually in SQLAlchemy...
related = db.relationship(SomeOtherFlaskSQLAlchemyModel, backref=db.backref('related_backref', lazy='dynamic'))
以这种方式定义 Flask-SQLAlchemy 模型的注意事项是它们依赖于 SQL 数据库。在尝试导入模型所在的 .py 文件之前,需要正确配置 Flask-SQLAlchemy 及其 db 对象,否则在导入时会出现一些令人讨厌的错误。如果将db 的定义与模型放在同一个文件中,它会像这样初始化:
from flask import current_app
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
db.init_app(current_app)
然后你需要像这样进行导入:
with app.app_context():
import module_with_flask_sqlalchemy_model
当然,app 需要使用 Flask-SQLAlchemy 的配置加载设置,否则将无法正常工作。通常最好让模型文件做from application import db,并在设置db 之后让application.py 做from my_models import *。
一旦正确配置,Flask-SQLAlchemy 模型将等同于这样定义的 Flask-SQLAlchemy 模型:
from flask import current_app
from flask_sqlalchemy import SQLAlchemy
import datetime
db = SQLAlchemy()
db.init_app(current_app)
class FlaskSQLAlchemyModel(db.Model):
__tablename__ = 'sql_table_name'
id = db.Column(db.Integer, primary_key=True)
field1 = db.Column(db.String(10))
field2 = db.Column(db.Integer)
field3 = db.Column(db.DateTime)
created_timestamp = db.Column(db.DateTime, default=datetime.datetime.now)
modified_timestamp = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)
related_id = db.Column(db.Integer, db.ForeignKey('some_other_sql_table_name.id'))
related = db.relationship(SomeOtherFlaskSQLAlchemyModel, backref=db.backref('related_backref', lazy='dynamic'))
一旦你得到了 django 模型和反射的 flask-sqlalchemy 模型,那么你可以使用 django 的真棒迁移命令来创建具有正确模式的表。然后,flask-sqlalchemy 模型会注意到它们已经被创建并自动填充它们自己。这样,您只需要担心 django 模型(减去时间戳字段和模型关系),然后让 flask-sqlalchemy 为您反映其余部分。
您需要做的最后一件事是将 Flask-SQLAlchemy 和 Django 配置为指向同一个 SQL 数据库。不过,我假设您知道该怎么做。我给你的一个提示是,Flask 和 Django 的 settings.py 可以是同一个文件而不会发生任何冲突。