我刚刚完成了第二次Django教程的学习,现在对事情的理解更加清晰了。然而,我仍然不清楚网站内的应用程序是如何相互作用的。
例如,假设我正在编写一个博客应用程序(显然是一个相当流行的活动)。博客文章和评论往往是一起发布的,但是它们足够清晰,应该被构建成独立的应用程序,就像Djano开发的一般哲学一样。
考虑下面的例子。实际上,我不会亲自编写评论应用程序,因为web上已经有了这方面的好代码,但这只是为了演示/实践:
mysite/blog/models.py
from django.db import models
class post(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
content = models.TextField()
mysite/comments/models.py
from django.db import models
from mysite.blog.models import post
class comment(models.Model):
id = models.AutoField()
post = models.ForeignKey(post)
author = models.CharField(max_length=200)
text = models.TextField()
我在上面写的,从另一个应用程序导入模型并将其设置为外键,Django应用程序是如何交互的?或者,对于组成站点的应用程序,有没有一种不同的/更好的方法来进行交互?
更新
根据一个回复中的建议,我正在阅读contrib.contenttypes的文档。如果我阅读正确,我可以重写我的示例评论应用程序,如下所示:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contentypes import generic
class comment(models.Model):
id = models.AutoField()
author = models.CharField(max_length=200)
text = models.TextField()
content_type = models.ForeignKey(ContentType)
content_object = generic.GenericForeignKey(content_type, id)
这是对的吗?
看看django内置的contenttypes framework:
django.contrib.contenttypes
它允许您将应用程序开发为独立的单元。这就是django开发人员用来允许django的内置comment framework将注释附加到项目中的任何模型的方法。
例如,如果有一些内容对象要“附加”到不同类型的其他内容对象,例如允许每个用户在博客文章、图像或用户配置文件上留下一个“最喜爱的”星,则可以创建一个
Favorite
模型,该模型使用generic relation field,如下所示:通过这种方式,您可以将来自任何用户的
Favorite
星添加到项目中的任何模型。如果要通过收件人模型类添加API访问,可以在收件人模型上添加一个reverse generic relation field(尽管这将“耦合”这两个模型,您说过要避免这样做),或者使用收件人实例的content_type
和object_id
通过Favorite
模型进行查找,请参见official docs示例。“我在上面写的,从另一个应用程序导入模型并将其设置为外键,Django应用程序是如何交互的?”
是的。对我有用。
我们有大约10份相互借阅的申请。
这会导致单元测试脚本中存在某种依赖关系。
看起来像这样。
“所有权”。我们有一个简单的数据所有权应用程序,它定义了其他应用程序所依赖的一些核心所有权概念。这里有几张简单的桌子。
“东西”。[不是真名]。我们的thing应用程序拥有不同用户组拥有的数据元素。这个应用程序的模型实际上有几个复杂的表。这取决于“所有权”。
“桌子”。[不是真名]。我们的一些用户创建了相当复杂的离线模型(可能有电子表格),并将建模结果上传到“表格”中。这有一组相当复杂的表。这取决于“所有权”。
“结果”。[不是真名]。我们的结果是基于拥有者的东西。结果基于事物和表格,是对客户请求的响应。这并不太复杂,可能只有两三个核心表。这取决于“东西”和“桌子”。不,它不是完全独立的。然而,它比它所依赖的其他事物受到更多的变化。这就是为什么它是分开的。
“正在处理”。我们安排和监控大批量作业。这是在这个应用程序中。它真的很普通,可以用多种方式。它完全独立。
“欢迎”。我们有一个“欢迎”应用程序,它呈现了一堆基本上是静态的页面。这里没有太多的桌子。但这是第二次,因为第一次太复杂了。它完全独立。
依赖应用程序之间的唯一关系是一些表名。只要我们保留这些表(和它们的键),我们就可以根据需要重新排列其他应用程序。
让某个应用程序依赖于另一个应用程序并没有错(imho)。毕竟,应用只是对一组模型的操作。你只要知道哪个应用程序依赖于哪个应用程序(我想你可以称之为依赖关系图)。
您可以实现与contenttypes框架的松耦合。它允许应用程序真正可移植/可插拔,但仍与其他应用程序集成。
我写了一个评论应用程序(是的,我重新发明了轮子),可以集成到任何其他应用程序中,页面模板中有几行评论应该发布(使用自定义标记)。
假设您希望模型“线程”可以插入到任何其他模型中。我们的想法是创建一个通用外键(参见django文档),编写一个小函数,它接受任何对象并返回与之对应的“线程”(或者在必要时创建一个线程),然后编写一个使用该功能的自定义模板标记,例如
{% get_thread for arbitrary_object as thread %}
。所有帖子都与线程相关,线程与对象相关,对象可以是任何类型。你可以把“thread”对象看作是一种代理,因此它不是与某个“文章”或“博客文章”相关的文章,而是与一个线程相关,线程在某种意义上是抽象的,什么是线程?只是一堆帖子而已。然后,线程允许自己与任何对象相关,而不管其类型如何。(尽管它做的不止这些,但它可以保存额外的信息,例如允许/不允许其他帖子、页面上的结束/打开注释等。)
编辑
以下是如何使用内容类型框架创建通用外键:
通过利用django假定所有对象都实现的隐式“common”接口,可以使它更加“透明”。。
相关问题 更多 >
编程相关推荐