python - 如何正确地将逻辑分离到单独的应用程序中?

标签 python django django-2.2

我实现了简单的 django 网站,我试图在不同的 APP 中将不同的部分与网站分开,但我遇到了一些问题:

我现在有两个 django 应用程序(核心 - 页眉、页脚、索引在哪里)和(对象 - 我有要在索引页面列出的对象):

核心/模板/header.html (标题元素、登录、注销等)

核心/模板/index.html (html标签、 block 等):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block 'head-title' %}
    {% endblock %}
    {% load static %}
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script
      src="https://code.jquery.com/jquery-3.4.1.min.js"
      integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
      crossorigin="anonymous">
    </script>
    <script src="{% static 'core/js/custom.js' %}"></script>
</head>
<body>
    {% include 'header.html' %}
    {% block 'body' %}
    {% endblock %}
</body>
</html>

核心/模板/home.html (主页 - 在这里我想列出所有对象并为它们实现过滤器):
{% extends 'index.html' %}

{% block 'body' %}
{% endblock %}

核心/views.py:
from django.shortcuts import render, redirect


def show_home_page(request):
    return render(request, "home.html")

好的,一切都很完美,但现在我不知道如何添加元素列表:

我尝试的是在 show_home_page() 中调用对象模型功能与 Object.objects.all()并将此列表传递给 home.html并让过滤器使用参数调用相同的函数,例如 def show_home_page(request, price_up, distance):但后来我搞砸了objects core 中的逻辑APP,我觉得不好。变体 2 是在 objects/views.py 中设置此逻辑但是我应该返回 home.html来自 objects我认为,这又是不正确的应用程序。

有任何想法吗?

最佳答案

试图保持功能(和层)良好解耦是一个值得称赞的目标,但你仍然需要让每个人在某个时候一起工作......这意味着你确实需要在某个地方进行一些耦合。

第一个明显的“集成层”候选者是模板——它们(大部分)是特定于项目的(一些可重用的应用程序提供模板,但这些通常用作示例/起点,可以根据您的项目需求进行定制),并且可以使用它们(连同自定义模板标签和上下文处理器)将来自不同应用程序的功能绑定(bind)在一起。

但有时您需要的不仅仅是模板层集成。我在大多数 django 项目中所做的就是让一个“主”应用程序充当“集成”层——这个应用程序可以依赖于任何其他应用程序,但不允许任何应用程序依赖它。这个应用程序通常会托管主页、基本模板、静态 Assets 等。

FWIW 我通常也有一个“核心”应用程序来提供项目域层的核心(模型、业务逻辑等),每个人都可以依赖但不允许依赖任何其他应用程序(当然 contrib 应用程序除外,例如auth 等)。

请注意(正如 Atcrank 已经提到的)实际上有两种 django 应用程序:可重用应用程序和特定于项目的应用程序。一个可重用的应用程序显然必须具有尽可能少的依赖项(当然,在您的项目特定应用程序上没有依赖项 - 看起来很明显),但它还必须提供尽可能多的“ Hook ”以与您的项目的特定需求集成(通过信号,自定义模板标签、可覆盖模板、抽象基类、mixins 等)。

特定于项目的应用程序 OTHO 是特定于您的项目的,因此只要您避免循环依赖,它就可以依赖于另一个应用程序 - 因此我的三明治式“核心应用程序主”模式提供了一个地方对于其他人都依赖的东西,以及依赖于其他人的东西的位置(以及其他功能之间的某个位置)。

在您的示例中,您命名的“核心”看起来实际上想要成为我自己的“主”层,而您命名的“对象”将是我的“核心”或某些特定于项目的应用程序。

One more question.. What about if in core/views.py call objects/views.py function which return list with objects (filtered or not) and pass this list to home.html (...) Or create something like service, which operate with Objects model



这不会改变太多 wrt/依赖项——而不是依赖于 objects.models ,您的核心应用程序现在依赖于 objects.views或某些“服务”(无论它应该是什么),它本身取决于 objects.models , 所以你用间接依赖替换直接依赖 - 这不太明显并且调试起来很痛苦(我曾经有一个循环导入问题通过 django 信号产生十几个间接级别,“聪明”黑客,动态导入等我可以告诉你追踪并不好玩)。

现在正如我所说,您必须以一种或另一种方式耦合您的应用程序以使它们一起工作,而这样做的两个明显地方是 1/模板层和 2/专用的“主”应用程序(你可以称之为不管你想要什么——我把它命名为“main”,因为它是应用程序入口点的规范名称——这里的重点是这个应用程序可以依赖于其他所有应用程序,但任何其他应用程序都不应该依赖它)。

如果您想使用模板作为集成层,例如 appA.views.somemodel_index 的模板可以显示来自 appB.models 的信息没有 appA对此一无所知,简单明显的解决方案是在 appB 中添加一些自定义模板标签这将检索/format/呈现这些信息并在模板​​中需要的地方使用此自定义模板标签。

但是在模板层你能做的只有这么多,一些需要了解模型/功能/来自不同的、假定不相关的应用程序的功能将在 View 或模型(信号等)层中更好地实现,因此使用一个“集成”应用程序。

关于python - 如何正确地将逻辑分离到单独的应用程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57752747/

相关文章:

python - 如何在linux上通过python代码进入文件夹

python - Django 2.2 不提供静态文件

django.core.exceptions.FieldError : Unknown field(s) (body ) specified for Comment

python-3.x - 如何更改 Django REST 框架中 URL 中的默认搜索查询参数?

django - 为什么 Django Rest Framework - 序列化程序验证不起作用

python - 同时安装 Anacondas 2.7 和 3.5 可以吗?

python - InvalidDocument : Cannot encode object: <pymongo. 游标。游标对象位于

python - 有没有办法修剪/去除 pandas 数据帧的多列中的空格?

python - 从 Django 获取多个随机对象时,查询集如何工作?

python - 在 TestCase 执行期间 django.db.connection.cursor() SQL 查询从主数据库返回数据,而不是从测试数据库返回数据