关于python:Django新手很难掌握模型和可重用的业务逻辑

Django newbie having hard time with models and reusable business logic

我是一个.NET开发人员,曾与ASP.NET MVC框架合作过,我试图将自己介绍给python世界,特别是试图使用django编写一些网站的代码,但我很难弄清楚django的结构。

在ASP.NET MVC中,我使用ASP.NET MVC框架作为表示层,我的业务逻辑和数据层是独立的。这是我的所有ASP.NET MVC站点的基本结构:

enter image description here

该网站是一个ASP.NET MVC项目,而业务逻辑和数据类型项目是类库(DLL)。在业务逻辑项目中,我使用实体框架模型(包括它生成的所有类),并创建一些我称为"管理器"的类,其中包含系统的核心逻辑。例如,如果webiste用于博客网站,"usersmgr"将包含以下操作"registeruser、getuser、confirmuseraccount","postmgr"将包含操作"addpost、removepost、editspost、addcomenttopost等"。

这种方法的思想是,网站只是一个表示层,它使用业务逻辑,但它并没有与之紧密耦合。我通常会添加一个"管理控制台"(另一个ASP.NET MVC网站,供管理员使用)、"某些合作伙伴的报告"(例如,假设博客上有广告,我们会给合作伙伴一个登录名,这样他们就可以更新广告并查看广告显示次数的报告等)、"REST API",这样如果我想创建一个移动应用程序,我可以通过RESTAPI、crons设置业务逻辑,以运行维护任务或每天结束时发送电子邮件的报告等。

在以前架构的.NET项目中,添加这些新内容如下:

氧化镁

基本上,所有这些新添加的项都是业务逻辑的"消费者"。

我很难理解如何用Django实现这种效果,因为Web应用程序似乎与它们的模型紧密耦合,这些模型映射到DB表。那么,如果我以后想在非Django网站中重用业务逻辑,我应该把它放在哪里呢?

关于django应用程序,我在各地都读到,在django应用程序中拆分网站是件好事,但是在通常概念结合的情况下,如何做到这一点。例如,一个博客可能有用户、文章、评论、标签等。我的问题是,所有东西都链接在一起,这些文章属于一个用户,这些标签和评论链接到一个文章。你对这种关系做了什么?

如果有人能帮助我,我会非常感激,我为我的覆盆子pi做了一些python脚本,它看起来是一种很棒的语言,但是我和Django在一起很困难。一定有什么东西我错过了…

谢谢!


视图和模型

模型相当于数据类型组件。视图相当于网站部分,通常包含"经理"将包含的代码。

我假设"业务逻辑"指的是"只有符合特定条件的用户才可以在帖子上发表评论"。那么直接把它放在视图中的权利就不太好了,因为如果你的用户可以用另一种方式访问系统(比如本地运行的命令行实用程序),那么你需要在那里重复这个逻辑。

答案是将业务逻辑添加到模型本身,方法是将自定义函数添加到模型类中,该类等同于经理的"getx"、"gety",并将类似"此用户可以这样做吗"的逻辑添加到模型的保存挂钩中。

没有什么可以阻止您在视图和模型之间创建管理器层,比如:

型号.py:

1
2
3
4
5
6
7
class Post(models.Model):
    ...

class Comment(models.Model):
    user = models.ForeignKey(User)
    post = models.ForeignKey(Post)
    text = models.CharField(...)

经理.py:

1
2
3
4
5
6
7
8
9
10
11
class PostManager(object):
    @staticmethod
    def getPost(id):
        return Post.object.get(pk=id)

    @staticmethod
    def addComment(post, comment_text, user):
        comment = Comment(post=post, user=user, text=comment_text)
        # check stuff
        comment.save()
    ...

视图.py:

1
2
3
4
5
6
def add_comment(request, post_id):
    ...
    PostManager.addComment(post=PostManager.getPost(post_id),
                           user=request.user,
                           request.POST['text'])
    ...

但这有几个缺点:

  • 模型实例的API仍然可以绕过这些检查
  • 你失去了模型API的表现力
  • 有点过于冗长了

其主要优点是,您可以无缝地将整个Django模型交换为一个完全不同的ORM。但如果这不是你可能做的事,那我就不会沿着这条路走了。

Django应用程序

把事情分成应用程序是个好主意。应用程序应该被划分成功能线,将整个项目所做的不同事情分开。

在您的示例(博客、帖子、评论、用户)中,您实际上有两个应用程序。处理用户(登录/注销、注册、密码重置等)和处理博客(发布、评论等)的人。

博客应用程序依赖于用户应用程序并不是坏事,利用用户应用程序提供的博客应用程序中的现有功能是有意义的。

归根结底,这可以方便地重用(您可能与用户有另一个项目,但不是博客)。


我见过很多开发人员对Django有同样的疑虑。问题是,Django对MVC的方法有点不同。DjangoORM抽象了与数据库本身的任何连接,并使模型处理业务逻辑。即使Django允许您处理自己的数据库结构、使用触发器、进程等,Django也可以在应用程序级别实现所有这些功能,使您的项目完全不受数据库影响。

Django还提倡使用胖模特和经理。django中的管理者可以在某个时刻取代MVC的控制器,因为他们的工作是处理模型实例的集合。但是,您可以扩展模型管理器以适应您习惯的指令。

数据库独立性对某些人来说是巨大的好处,它还意味着你的数据模型与Django项目相关联,在其他项目中使用它的用处很小,但是,嘿,这就是接口的用途!

管理应用程序内置在Django中,很容易根据您的需要进行定制。

谈到界面,Django的视图只是一个界面。它没有告诉你应该如何呈现你的数据。Django有一个非常强大的模板框架,但它确实是可选的。如果您试图实现一个REST接口,Django REST框架或Django Tastypie可以在几个小时内完成这项工作,因为您的所有业务逻辑都已经用一种通用语言定义了,并且这些应用程序都从中受益,并完美地公开了该逻辑。

现在转到应用程序部分。从特性方面考虑您的项目:用户可以是一个,注册应该是另一个,博客,评论,标签管理。用户可以拥有用户、个人资料和群组模型,注册不需要模型,博客拥有帖子和分类模型,标签管理处理标签模型。

应用程序只是打包好的功能,它们有模型、视图、URL等,可以让它们一起工作。您可以在应用程序之间建立关系(博客文章有许多标记)。当然,如果你删除了标签应用程序,博客可能现在就要崩溃了,所以请提前考虑这些事情(也许是标签有很多博客文章)。

如果你还有什么问题,请在评论中问我,我会尽量澄清。