核心理念 Core Concepts
- keep It Simple, Stupid
Simplelicity is the ultimate sophistication - Fat Models, Utility Modules, Thin Views, Stupid Templates
- Start With Django By Default
- Be Familiar with Django's Design Plilosophies
- The Twelve-Factor App
1.编码风格 Coding Style
The Word on Imports
- Standard library imports
- Related third-party imports
- Local application or library specify imports
In Django project:
- Standard library imports
- Imports from core Django
- Imports from third-party apps including those unrelated th Django
- Imports from the apps that you created as part of your Django project.
Use Explictit Relative Imports
bad imports include hardcoded import
# cones/views.py
from django.views.generic import CreateView
from cones.models import WaffleCone
from cones.forms import WaffleConeForm
from core.views import FoodMixin
class WaffleConeCreateView(FoodMixin, CreateView):
model = WaffleCone
form_class = WaffleConeForm
Sure, your cones app works nice within your ice cream tracker project, but it has those nasty hardcoded
imports that make it less portable and reusable:
- What if you wanted to reuse your cones app in another project that tracks your general dessert
consumption, but you had to change the name due to a naming confict (e.g. a confict with a
Django app for snow cones)? - What if you simply wanted to change the name of the app at some point?
在两种情况下硬编码的导入会变得不方便和不可复用:
- 需要在其他项目使用
cones
app但是因为命名冲突需要改名 - 某些情况下你想改变app的名字
correct example
# cones/views.py
from django.views.generic import CreateView
from .models import WaffleCone
from .forms import WaffleConeForm
from core.views import FoodMixin
class WaffleConeCreateView(FoodMixin, CreateView):
model = WaffleCone
form_class = WaffleConeForm
2. The Optimal Django Environment Setup
Use the Same Database Engine Everywhere
virtualenvwrapper is better than virtualenv
3. How to Lay Out Django Project
/
/
/
4. Fundamentals of Django App Design
The Golden Rule of Django App Design
James Bennett volunteers as both a Django core developer and as its release manager. He taught us
everything that we know about good Django app design. We quote him:
“ The art of creating and maintaining a good Django app is that it should follow the
truncated Unix philosophy according to Douglas McIlroy: ‘Write programs that do one
thing and do it well.”’
In essence, each app should be tightly focused on its task. If an app can’t be explained in a single
sentence of moderate length, or you need to say ‘and’ more than once, it probably means the app is
too big and should be broken up.
When in Doubt, Keep Apps Small
Don’t worry too hard about getting app design perfect. It’s an art, not a science. Sometimes you have
to rewrite them or break them up. at’s okay.
Try and keep your apps small. Remember, it’s better to have many small apps than to have a few
giant apps.
Uncommon App Modules
scoops/
behaviors.py
constants.py
context_processors.py
decorators.py
db/
exceptions
fields.py
factories.py
helpers.py
managers.py
middleware.py
signals.py
utils.py
viewmixins.py
behaviors.py : An option for locating model mixins per subsection.
constants.py : A good name for placement of app-level settings. If there are enough of them involved
in an app, breaking them out into their own module can add clarity to a project.
decorators.py Where we like to locate our decorators. For more information on decorators.
db/ Used in many projects for any custom model elds or components.
fields.py is commonly used for form elds, but is sometimes used for model elds when there isn’t
enough eld code to justify creating a db/ package.
factories.py Where we like to place our test data factories. Described in brief in subsection.
helpers.py What we call helper functions. ese are where we put code extracted from views and models to make them lighter. Synonymous with utils.py
managers.py When models.py grows too large, a common remedy is to move any custom model
managers to this module.
signals.py While we argue against providing custom signals (see chapter 28), this can be a useful
place to put them.
utils.py Synonymous with helpers.py
viewmixins.py View modules and packages can be thinned by moving any view mixins to this mod-
ule.
5.Settings and Requirements Files
Avoid Non-Versioned Local Settings 避免无版本的本地设置
We used to advocate the non-versioned local settings anti-pattern. Now we know better.
As developers, we have our own necessary settings for development, such as settings for debug tools
which should be disabled (and often not installed to) staging or production servers.
Furthermore, there are often good reasons to keep specifc settings out of public or private code
repositories. The SECRET_KEY setting is the first thing that comes to mind, but API key settings to
services like Amazon, Stripe, and other password-type variables need to be protected.
A common solution is to create local settings.py modules that are created locally per server or develop-
ment machine, and are purposefully kept out of version control. Developers now make development-
specific settings changes, including the incorporation of business logic without the code being tracked
in version control. Staging and deployment servers can have location specifc settings and logic with-
out them being tracked in version control.
What could possibly go wrong?!?
Ahem...
- Every machine has untracked code.
- How much hair will you pull out, when after hours of failing to duplicate a production bug
locally, you discover that the problem was custom logic in a production-only setting? - How fast will you run from everyone when the ‘bug’ you discovered locally, fixed and pushed
to production was actually caused by customizations you made in your own local settings.py
module and is now crashing the site? - Everyone copy/pastes the same local settings.py module everywhere. Isn’t this a violation of
Don’t Repeat Yourself but on a larger scale?
我们曾经提倡无版本的反模式本地设置,现在我们了解的更多。
作为开发者, 我们各自拥有针对开发环境的重要设置, 比如为了解决问题工具的设置, 但这个在生产服务中禁用。
长远的看,让特殊的设定远离公共或者私人的仓库有很多理由。SECRET_KEY的设置是第一个需要保护的,不仅如此, 其他服务的API设置或者是需要密码保护的变量同样需要保护。
一个通用的设置是为每个服务或者开发机器创建一个本地的setting.py,并且让它们脱离版本控制。开发者做了为开发环境制定的设定改变,包括没有在版本控制中追踪的事务逻辑合并。状态和开发服务拥有本地的特别设定和脱离版本控制的逻辑。
会不会出现问题呢?
然而。。。
- 每一台服务器都有有无法追踪的代码
- 每当你失败地复制一个生产环境问题到本地,你发现开发环境的问题存在于一个特定的本地逻辑,这花掉的时间要掉多少头发呢?
- 由于你的个人本地设置模块放在每一个环境,网站奔溃了, 你需要多快才能在每一个环境里发现本地的设置问题, 修复并且推送到开发环境呢。
- 每个人到处复制粘贴同样一个settings.py, 在打的方向上是不是和不要重复你自己冲突了?