在Django中,实用函数应该存放在哪里?

67
在Django中应该把实用函数存放在哪里?例如自定义加密/解密数字、发送推文、发送电子邮件、验证对象所有权、自定义输入验证等重复和自定义的内容,这些功能在我的应用程序中多处使用,目前我违反了DRY原则。
我看到一些演示将函数定义在models.py中,但那似乎并不符合概念上的正确性。它们应该放在一个“utilities”应用程序中,以被导入到我的项目中吗?如果是这样,它们应该放在utilities应用程序的哪个位置?是否应该放在那里的models.py文件中?
谢谢帮助这个新手。
更新:更具体地说,假设我需要一个名为"light_encrypt(number)"的函数,它采用参数"number",将其乘以7,加上10并返回结果,另一个函数"light_decrypt(encr_number)"采用参数“encr_number",减去10,除以7并返回结果。在我的Django树中,我应该将其放在哪里?这不是中间件,对吗?就像Felix建议的那样,我要创建一个Python包,并将其导入到需要这些函数的视图中吗?

1
你可以创建一个普通的Python包。 - Felix Kling
1
相关:https://dev59.com/uXA75IYBdhLWcg3wkZ6A#3224926 - eruciform
4个回答

37

不同的问题,但是相同的答案:

My usual layout for a django site is:

projects/
templates/
common/
local/

Where:

  • projects contains your main project and any others
  • common contains things you may share across sites, or are at least not project-specific, like if you need to download django-profile and django-registration rather than having it directly in python/site-packages
  • templates contains just that
  • local contains things that are going to be specific to the current machine, so that you can have properly separated data, like database location and password - I then soft-link the machine-specific versions (say "machine1-localconfig.py") to local/localconfig.py and then can "import localconfig" in settings.py
  • I generally put middleware that's project-specific inside a project, and middleware that's not project-specific in common/middleware/
  • make sure to add the templates directory to the right place in settings (or most probably, localconfig.py and then import it in settings), and makse sure to add the projects, common, and local directories to your PYTHONPATH.

1
谢谢您的回复,eruciform。那么,针对我上面的“light_encrypt(number)”示例,您建议我将其放在公共区域中? - mitchf
1
如果你将来要在另一个项目中使用它,最好将其放在common/util/encrypt.py(或其他位置),并确保它没有内部链接到任何特定于项目的内容。这样更容易重用,如果以后需要移动东西,也更容易移植。从数据隐藏的角度来看,这也更加清晰。 :-) - eruciform
11
如果你将其放在common/util/encrypt.py中,请确保触碰一个空白的common/util/__init__.py,以便from common.util.encrypt import light_encrypt正常工作。 - eruciform

28

好的,在阅读这里的评论和答案后,我决定在我的项目目录中创建一个名为“common/util/”的目录。在这个目录中,我有一个文件“__ init__.py”,其中包含我的一些辅助函数。

我想如果这个文件变得太大,那么我将把这些函数拆分成独立的.py文件放在common目录中。所以现在,我的项目结构看起来像这样。如果我做出了任何不好的选择,请纠正我,我还处于开发的早期阶段,现在可以很容易地进行修复!

myproject/         (Django project) 
  common/  
    util/
      __init__.py  (helper functions)  
  middleware/      (custom middleware)  
  templates/       (project templates)  
  myapp/
    fixtures/      (initial data to load)
    migrations/    (south migrations)
    urls/
    views/
    admin.py
    forms.py
    models.py
    test.py

 public/           (static stuff not served by Django)
   media/
     css/
     img/
     js/
     lib/

1
值得一提的是,我在django-profiles应用程序中看到了ubernostrum创建了一个utils.py文件,与urls.py和views.py位于同一目录中,以保存他的实用功能函数。 - mitchf
在这里顺便提一下Python中的常见习语,即将你想要放在模块级别上但可以/应该分开存放在自己的文件中的东西导入到__init__.py中。http://mikegrouchy.com/blog/2012/05/be-pythonic-__init__py.html是一个很好的介绍。 - Hylidan

5

这里有另一种方法:

如果实用程序函数可以作为独立模块存在,并且您正在为Django应用使用virtualenv环境,则可以将功能捆绑为包并将其安装在虚拟环境中。

这样,您就可以轻松地在Django应用程序中任何需要的位置导入它。


17
可以展示一下如何制作一个简单的软件包,这样会很不错。 - dalore

4

这取决于函数是针对项目还是应用程序特定的。

其他答案已经回答了针对项目特定函数的放置位置。更准确地说,将其放在项目根目录下名为common的文件夹中。

如果我们谈论的是应用程序特定的函数,则我只需将其放在名为utils.py的文件中,放在应用程序内部即可。

myproject/         (Django project) 
  common/  
    util/
      __init.py__    (project app specific functions)  
  myapp/
    migrations/    (myapp migrations)
    utils.py            (myapp specific functions)
    views.py
    admin.py
    forms.py
    models.py
    test.py

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接