初学者:试图了解Djang中的应用程序是如何交互的

2024-05-12 21:48:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚刚完成了第二次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)  

这是对的吗?


Tags: djangofromimport应用程序dbmodelmodels评论
3条回答

看看django内置的contenttypes framework

django.contrib.contenttypes

它允许您将应用程序开发为独立的单元。这就是django开发人员用来允许django的内置comment framework将注释附加到项目中的任何模型的方法。

例如,如果有一些内容对象要“附加”到不同类型的其他内容对象,例如允许每个用户在博客文章、图像或用户配置文件上留下一个“最喜爱的”星,则可以创建一个Favorite模型,该模型使用generic relation field,如下所示:

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Favorite(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

通过这种方式,您可以将来自任何用户的Favorite星添加到项目中的任何模型。如果要通过收件人模型类添加API访问,可以在收件人模型上添加一个reverse generic relation field(尽管这将“耦合”这两个模型,您说过要避免这样做),或者使用收件人实例的content_typeobject_id通过Favorite模型进行查找,请参见official docs示例。

“我在上面写的,从另一个应用程序导入模型并将其设置为外键,Django应用程序是如何交互的?”

是的。对我有用。

我们有大约10份相互借阅的申请。

这会导致单元测试脚本中存在某种依赖关系。

看起来像这样。

  • “所有权”。我们有一个简单的数据所有权应用程序,它定义了其他应用程序所依赖的一些核心所有权概念。这里有几张简单的桌子。

  • “东西”。[不是真名]。我们的thing应用程序拥有不同用户组拥有的数据元素。这个应用程序的模型实际上有几个复杂的表。这取决于“所有权”。

  • “桌子”。[不是真名]。我们的一些用户创建了相当复杂的离线模型(可能有电子表格),并将建模结果上传到“表格”中。这有一组相当复杂的表。这取决于“所有权”。

  • “结果”。[不是真名]。我们的结果是基于拥有者的东西。结果基于事物和表格,是对客户请求的响应。这并不太复杂,可能只有两三个核心表。这取决于“东西”和“桌子”。不,它不是完全独立的。然而,它比它所依赖的其他事物受到更多的变化。这就是为什么它是分开的。

  • “正在处理”。我们安排和监控大批量作业。这是在这个应用程序中。它真的很普通,可以用多种方式。它完全独立。

  • “欢迎”。我们有一个“欢迎”应用程序,它呈现了一堆基本上是静态的页面。这里没有太多的桌子。但这是第二次,因为第一次太复杂了。它完全独立。

依赖应用程序之间的唯一关系是一些表名。只要我们保留这些表(和它们的键),我们就可以根据需要重新排列其他应用程序。

让某个应用程序依赖于另一个应用程序并没有错(imho)。毕竟,应用只是对一组模型的操作。你只要知道哪个应用程序依赖于哪个应用程序(我想你可以称之为依赖关系图)。

您可以实现与contenttypes框架的松耦合。它允许应用程序真正可移植/可插拔,但仍与其他应用程序集成。

我写了一个评论应用程序(是的,我重新发明了轮子),可以集成到任何其他应用程序中,页面模板中有几行评论应该发布(使用自定义标记)。

假设您希望模型“线程”可以插入到任何其他模型中。我们的想法是创建一个通用外键(参见django文档),编写一个小函数,它接受任何对象并返回与之对应的“线程”(或者在必要时创建一个线程),然后编写一个使用该功能的自定义模板标记,例如{% get_thread for arbitrary_object as thread %}。所有帖子都与线程相关,线程与对象相关,对象可以是任何类型。

你可以把“thread”对象看作是一种代理,因此它不是与某个“文章”或“博客文章”相关的文章,而是与一个线程相关,线程在某种意义上是抽象的,什么是线程?只是一堆帖子而已。然后,线程允许自己与任何对象相关,而不管其类型如何。(尽管它做的不止这些,但它可以保存额外的信息,例如允许/不允许其他帖子、页面上的结束/打开注释等。)

编辑

以下是如何使用内容类型框架创建通用外键:

from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType

class Thread( models.Model ):
    object_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    object = generic.GenericForeignKey('object_type', 'object_id')

通过利用django假定所有对象都实现的隐式“common”接口,可以使它更加“透明”。。

    #inside the Thread class:
    def __unicode__(self):
        return unicode(self.object)
    def get_absolute_url(self):
        return self.object.get_absolute_url()

相关问题 更多 >