Django 应用间导入的公认做法是什么

rh0*_*ium 6 python django

Django 和相互交互的应用程序很容易遇到导入问题。我的问题很简单:

最小化循环进口的公认流程是什么,或者是否有人提出了公认的编码标准来减少他们愿意分享的这些?

我正在寻找可以标准化的良好原则。

楷模

class Program(models.Model):
    group = models.ForeignKey(Group, related_name="%(app_label)s_%(class)s_related") 
Run Code Online (Sandbox Code Playgroud)

对比

class Program(models.Model):
    group = models.ForeignKey('auth.Group', related_name="%(app_label)s_%(class)s_related") 
Run Code Online (Sandbox Code Playgroud)

意见:

class ProgramDetailView(DetailView):
    """Detail view of the EEP Program"""

    def get_queryset(self):
        """Narrow this based on your company"""
        from apps.company.models import Company
        company = Company.objects.get(name="foo")
        return Program.objects.filter(company = company)
Run Code Online (Sandbox Code Playgroud)

vs(这往往会导致问题..

from apps.company.models import Company
class ProgramDetailView(DetailView):
    """Detail view of the EEP Program"""

    def get_queryset(self):
        """Narrow this based on your company"""
        company = Company.objects.get(name="foo")
        return Program.objects.filter(company = company)
Run Code Online (Sandbox Code Playgroud)

这样做的问题是你倾向于在所有地方进行大量导入。

ran*_*lan 1

多年来,根据我对如何开发网络应用程序的观察,我对一些模式进行了标准化。

我不知道您关于模块化和代码重用的标准是什么,但以下简单的规则/模式对我处理一些相当大的项目有很大帮助。

我注意到我的许多模型都有一些共同的属性。例如,我更喜欢使用 UUID 而不是简单的自动递增整数作为主键。

所以我有这个抽象模型。

class UUIDModel(models.Model):
    id = UUIDField(primary_key=True, auto=True)  # There are many implementation of this on the web. Choose your favorite.

    class Meta:
        abstract = True
Run Code Online (Sandbox Code Playgroud)

我的许多模型都需要 的概念activation。所以我有另一个抽象模型,类似于:

class ActivatedModel(Model):
    is_active = models.BooleanField(default=False)

    def activate(self, save=True):
        if self.is_active:
            raise Exception('Already activated')
        self.is_active = True
        if save:
            self.save()

    class Meta:
        abstract = True
Run Code Online (Sandbox Code Playgroud)

我还使用许多其他抽象模型来跟踪创建时间和修改,或者某些内容是否finalized可以进一步修改,等等。

所有这些抽象模型都存在于core应用程序中。我就是这么称呼它的。除了core应用程序之外,我还有一个tasks应用程序。该应用程序提供了抽象模型,可以增强我与经常使用的celerytasks相关的任何接口。

应用tasks程序可以从core应用程序导入模型,但反之则不行。

我还有一个mms应用程序,它处理多媒体创建和转换(缩略图等)。可以mms从以前的应用程序导入模型。所以我们现在的导入关系是这样的:core ->tasks ->mms。

我创建的每个其他应用程序都特定于我正在处理的当前项目,并基于以前的应用程序构建。所以基本上我尝试进行“单向导入”(如果你可以这样称呼的话)。

我最终得到的模型看起来与此类似:

# models.py of an app called  "articles"

from core.models import UUIDModel, ActivatedModel
from tasks.models import ManagedTasksModel

class Article(UUIDModel, ActivatedModel, ManagedTasksModel):
    title = models.CharField()
    # blah...
Run Code Online (Sandbox Code Playgroud)

如果应用程序变得太大,我会按照上述规则将models.py模块分解为更小的模块,从而对应用程序进行“微观管理”。我发现这可以满足我的大部分需求。

我无法评论基于类的视图,因为老实说我不喜欢它们,而且它几乎总是让我编写更多代码而不是更少。每个人都有自己的。我更喜欢使用辅助实用函数,并在视图函数中充分利用诸如上下文处理器之类的东西。

我希望我的回答是在您的问题的范围内。

编辑:我刚刚注意到你的用法,related_name我认为它错过了该选项的要点。请参见以下示例:

class Message(models.Model):
    sender   = models.ForeignKey(User, related_name='messages_sent')
    receiver = models.ForeignKey(User, related_name='messages_received')
    body     = models.Textfield()
Run Code Online (Sandbox Code Playgroud)

通过上面的模型我们可以做到这一点,这是非常可读的:

u1 = User.objects.get(...)
received = u1.messages_received.all()
Run Code Online (Sandbox Code Playgroud)

...它描述了这种关系的功能目的。Sorelated_name不仅用于具有唯一的相关名称。