我正在使用Python构建一个非常小的API,并且想知道在使用诸如Django或Flask(带有Peewee或Pony之类的ORM)之类的框架时,将API代码放置在模型类中通常是否可以接受。让我解释一下我的意思...
为说明我的意思,假设我有一个包含所有模型的程序包,然后是另一个包含我的API代码的程序包,当客户端ping我定义的特定路由时执行该程序包。如您所知,这些模型基本上仅用于将对象映射到数据库。尽管在某些情况下,出于某些原因,将某些API代码放在我定义的模型类之一中更有意义。
例如,我有一个将用户映射到数据库的用户模型。另外,在API代码中,我有一个用于登录用户的功能。此功能基本上将cookie设置为登录用户,因此将其放置在API包中可能有意义。但是,我觉得如果将此函数用作方法并将其放置在用户模型中,则它在语义上更有意义,并且可能更易于理解。
class UserModel(Peewee or Pony or Django.model...):
def login(self):
"""" Login code goes here. Set cookies, login the user, etc. """
add_cookies(self.username)
return jsonify({"logged_in": True}) # Flask example...
user = UserModel()
user.login()
但是,这样做的一个警告是,模型代码和API代码不再分离,现在彼此之间非常依赖。
因此,我想我的“客观”问题是关于这些问题的可接受性。使模型(数据库和ORM之类的东西)和API路由保持解耦比将它们组合在一起更好的做法吗?每种方法都有哪些优缺点?最常见和推荐的做法是什么?
先谢谢了。
答案 0 :(得分:0)
TL; DR:可以在模型类中放置一个函数,但是如果您想进行安全登录,则需要使用Flask-Login之类的东西在令牌中传递登录信息(我不确定等效扩展名是django)。
在类中放置一个函数很好,但是这对于登录来说并不是很安全,所以我建议遵循一个教程来实现安全的登录扩展。
例如,在我的一个项目中,登录页面的视图功能为:
@user.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(next=request.args.get('next'))
if form.validate_on_submit():
u = User.find_by_identity(request.form.get('identity'))
if u and u.authenticated(password=request.form.get('password')):
if login_user(u, remember=True) and u.is_active():
# Handle optionally redirecting to the next URL safely.
next_url = request.form.get('next')
if next_url:
return redirect(safe_next_url(next_url))
return redirect(url_for('user.settings'))
else:
flash('Identity or password is incorrect.', 'error')
return render_template('user/login.html', form=form)
请注意,u.authenticated
是我的用户模型类中的一个函数,用于检查用户密码哈希是否正确:
def authenticated(self, with_password=True, password=''):
#Ensure a user is authenticated, and optionally check their password.
if with_password:
return check_password_hash(self.password, password)
return True
答案 1 :(得分:0)
TL; DR:您的login
方法(仅与HTTP相关的内容)不属于模型层,即周期。
最长的答案:向模型中添加逻辑当然是一个好的设计,但这必须是 domain 逻辑,而不是与UI相关的东西。重点(因为您询问“好的做法”)是使域层(模型)完全独立于UI(视图和控制器),因此您可以将同一域层用于不同的UI(请记住,命令行脚本是UI)。
我不得不处理许多设计不当的应用程序/框架,这些应用程序/框架混合了各种顾虑,并且实际上是必需,无论您想做什么,手头都有一个“请求”(http请求)和“响应”对象而且这些都是一场完整的噩梦,因此从经验上讲,“关注点分离”规则并不是您想要打破的。
请注意,这并不意味着UI层不应该了解域-这是没有意义的,并且实际上从技术POV来说是不可能的。