如何将多个可重用的Django应用程序绑定在一起?

Jas*_*nTS 18 python django django-1.4

我尽力编写可重用的Django应用程序.现在我很困惑如何把它们放在一起以获得最终的项目.

这是我的意思的一个例子:我有一个存储,调整大小和显示图像的图片应用程序.此外,我还有一个存储,编辑和显示文本的博客应用程序.现在我想结合这两个来展示带有图像的博客文章.

为此,我可以在博客中放置外键字段以指向图片.但是如果没有图片应用,博客就无法使用.我也可以创建第三个应用程序,它负责连接两者.

这种"最佳实践"方式是什么?

编辑:谢谢你的非常好的答案,但我仍然在寻找更实际的例子来解决这个问题.完成我的示例:有时使用没有图片应用程序的博客应用程序会很好.但如果我硬编码依赖,那就不再可能了.那么第三个应用程序如何结合两者?

小智 16

在答案的底部介绍谈话(更直接的答案).我假设您有一个名为Text的文本处理应用程序和一个名为Pictures的图片处理应用程序和第三个名为Blog的博客应用程序.

大图

您将需要学习有关python程序员的模板语言的手册.我们的想法是,每个东西都在自己的应用程序中,并且您有第三个连接所有内容的应用程序.然后应用程序应该按照您的喜好提供其模型和视图(只记得让您专注于应用程序应该做的事情),并提供一组模板标签.

如何制作包含标签

制作包含标签,非常简单!它会提醒您编写正常视图.

在您的app文件夹中创建目录templatetags.还要__init__.py在此templatetags中创建一个文件(因此该目录将成为python包).

然后创建一个python文件.名称很重要,您将在{% load xyz %}将使用您的应用程序的模板中使用此名称.例如,如果调用该文件picturestags.py,您将调用
{% load picturestags %}将使用它的所有模板.

首先在文件中添加一些你不需要考虑的政治,只需在其他任何事情之前加入:

from django.template import Library
register = Library()
Run Code Online (Sandbox Code Playgroud)

然后通过定义与标记同名的函数来添加标记.我将在示例中将其称为display_picture,它将采用一个参数url.该函数应创建一个将在模板中使用的字典.我的例子只显示url指向的图片.

@register.inclusion_tag('pictures/display_picture.html')
def display_picture(url):
    return {'picture': url}
Run Code Online (Sandbox Code Playgroud)

在您的应用中创建路径模板/图片,并在其中创建包含以下内容的文件display_picture.html:

<img src="{{ picture }}" />
Run Code Online (Sandbox Code Playgroud)

正如您可能理解的那样,@ register使它成为一个标记,字典display_picture返回的内容是您可以在display_picture.html中使用的内容.非常像您的普通视图功能.

最后,您将得到这些文件:

pictures/
    __init__.py
    models.py
    views.py
    tests.py
    templates/
        pictures/
            display_picture.html
    templatetags/
        picturetags.py
Run Code Online (Sandbox Code Playgroud)

这就是您需要添加到Picture应用程序的所有内容.要在博客应用中使用此功能,您需要将图片添加到INSTALLED_APPS.然后在模板中,你需要使用你自己的新家烘焙标签首先加载它:{% load picturestags %}然后只需添加如下标签{% display_picture https://www.google.com/intl/sv_ALL/images/logos/images_logo_lg.gif %}:

{% load picturestags %}
<html>
    <body>
        {% display_picture https://www.google.com/intl/sv_ALL/images/logos/images_logo_lg.gif %}
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

结果

这只是一个小例子,但你可以看到扩展它很容易.您的博客可以通过导入模型和外键来连接文本和图片应用程序.您可以连接特定博客文章的文字和图片.您的blog_post.html模板看起来像(简化):

{% load picturestags %}
{% load texttags %}
<html>
    <body>
        <h1>{{ subject }}</h1>
        <div class="article">{% article_to_html articleid %}</div>
        <div class="article_picture">{% display_picture %}</div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

请注意,只有Blog具有依赖关系,它应该具有依赖关系(没有文本和图片的博客......但图片可以没有文本生活).外观和位置应该并且可以由CSS和DIV/SPAN标签控制.通过这种方式,您可以将您的Picture应用程序交给不了解Text应用程序并使用它的人,以不同的方式显示图片,而不必触及您的代码!

自从我昨天刚开始学习以来,包含标签是我唯一知道的.我认为Django为简化生活提供了便利.在文档页面上还有更多内容(包括如何在没有"快捷方式"的情况下使用"真正的"标签.因此,如果您发现此方法有限,请阅读文档......它有很多示例.它还讨论了如何制作过滤器,simple_tags,线程注意事项和其他高级内容.

介绍

我有这个问题,因为你和我也想要一些与我读到的答案不同的东西(我不是说答案很糟糕,他们帮助我学到了很多并给了我见解,但我想要这个我现在正在写作) .我设法想出一些不太明显的东西,多亏了你的问题,并且非常感谢Stack Overflow所以这是我的贡献,即使是一个半年前的问题,可能会被放弃(可能会帮助一个或两个googler)!

我也从Google Tech Talk可重用应用程序中获得了很多灵感.最后(43分钟),他提到了一些很好的例子,例如django-tagging,这就是他所说的如何编写可重用应用程序的模型.这给了我所有这一切的想法,因为这就是django-tagging解决了我们已经拥有的这个问题的方式.

现在我写了这一切(花了一个小时)之后,我第一次觉得我可能会贡献而不仅仅是google并跟随其他人正在做的事情或抱怨其他人没有写我需要做什么.我第一次负责写我的观点,所以其他人可以谷歌这个(只需写下这段:-)因为它感觉真的很棒,即使它可能被撕成碎片或被忽略和遗忘).


Chr*_*att 6

您可以像在项目中使用任何第三方应用程序一样考虑它."可重用"并不意味着"没有依赖".相反,你很难找到一个没有至少一个依赖关系的应用程序,即使它只依赖于Django或核心Python库.(虽然核心Python库通常被认为是"安全"的依赖关系,即每个人都会拥有它,但事情有时会在Python版本之间发生变化,因此您仍然会将应用程序锁定到特定的时间点).

可重用的目标与DRY的目标相同:您不想一遍又一遍地编写相同的代码.因此,突破像图片应用程序这样的功能是有意义的,因为您可以在其他应用程序和项目中反复使用它,但您的图片应用程序将具有依赖性,而其他程序包将依赖于它,只要没有循环依赖,你很好(循环依赖意味着你实际上没有分离功能).


Jos*_*ton 5

这是一个很好的问题,我觉得很难管理.但是 - 你认为这些应用程序是公开发布的,还是你自己只使用它们?如果你没有发布,我不会担心它.

另一件事是,依赖是很好的.您的示例中的图片应用程序听起来像是一个"可重用"应用程序的良好候选人.它很简单,做一件事,并且可以被其他应用程序使用.

另一方面,博客应用程序通常需要使用其他应用程序,如图片应用程序或标记应用程序.我发现这种依赖很好.你可以尝试通过简单地链接到你的图片应用程序放在那里的媒体资源来抽象一点.

这只是一点常识.你能让你的应用变得苗条吗?如果是,则尝试创建它们以便可以重复使用.但是,当它们有意义时,不要害怕接受依赖.此外,尝试允许扩展点,以便您可以替换其他的依赖项.直接外键在这里没有帮助,但可能像信号或Restful API之类的东西.