Some suggestions for Python's Django Framework deployment _python

Source: Internet
Author: User

"What is the best layout for Django applications, profiles, and various other related directories?" ”

There are always friends who ask us this question, so I want to take a moment to write about how we look at the problem, so that we can easily let others refer to the document. Please note that this is based on the Django 1.7.1 version, but it can be easily applied to any version after Django 1.4.

Although Django 1.4 was released with an improved project layout (which took a long time), this article has some better suggestions for optimizing the layout of the project.
Why is this layout better?

The project layout We recommend here has several advantages, namely:

    1. Lets you get, repackage, and reuse a single Django application for other projects. This is usually ambiguous, as you are building an application that will be reused regardless of whether or not. Building apps in a way that you want to reuse in the first step makes this easier.
    2. Encourage the design of reusable applications.
    3. Detailed settings for the environment. In a single overall configuration file, if Debug==true does not make any sense. This makes it easy to see which configurations are shared and which can be overridden on a per-environment basis.
    4. Specific installation requirements for the environment (PIP requirements).
    5. If necessary, project-level templates and static files can overwrite the default values at the application level.
    6. Small and more specific test files are easier to read and understand.

Suppose you have two application blogs and users, and two development environment Dev and prod. Your project layout structure should be like this:

Copy Code code as follows:

myproject/
manage.py
myproject/
__init__.py
urls.py
wsgi.py
settings/
__init__.py
base.py
dev.py
prod.py
blog/
__init__.py
models.py
managers.py
views.py
urls.py
templates/
blog/
Base.html
List.html
Detail.html
static/
...
tests/
__init__.py
test_models.py
test_managers.py
test_views.py
users/
__init__.py
models.py
views.py
urls.py
templates/
users/
Base.html
List.html
Detail.html
static/
...
tests/
__init__.py
test_models.py
test_views.py
static/
css/
...
js/
...
templates/
Base.html
Index.html
requirements/
Base.txt
Dev.txt
Test.txt
Prod.txt

The remainder of this article describes how to migrate projects to this layout, and why this layout is better.
Current default Layout

We'll call the Sample project Foo, and I know it's a very creative name. Let's assume that here we're going to start foo.com. But when we want to map our project names to the final domain name, the project will exist here in a way that is not in any sense required.

If you use the django-admin.py startproject foo command to open this project, you will get a directory structure like this:

foo/
  manage.py
  foo/
    __init__.py
    settings.py
    urls.py

This layout is a good starting point, we have a top-level directory foo, which contains the manage.py file and the project directory foo/foo/. In this directory, you can query the source control system (such as Git).

You should think of subdirectories foo/foo/is this project. All files here, not a Django application, are related to the project's supporting files.
Modify Configuration

The task here is to fix the bad configuration file. I'm showing this layout to new users, and I'm often amazed at how these people know it might even work. In fact, when everyone knows that these configurations are just Python code, they don't use them as Python code.

So let's improve the configuration. For OO projects, there will be 4 development environments: Dev, stage, Jenkins, and production. Give each development environment a profile of their own. The thing to do in this process is:

Create a new configuration directory in the foo/foo/directory, creating an empty __init __.py file inside.
foo/foo/settings.py The move and rename it to foo/foo/settings/base.py.
Create separate dev.py, stage.py, jenkins.py, and production.py files under the foo/foo/settings/directory. The specific configuration files for these four environments should contain the following:

  From base Import *

Why is this important? For local development you want to set debug=true, but it's easy to accidentally push this into the production code, so you need to open the foo/foo/settings/production.py file and add Debug=false after the initial import base. Now, for this stupid mistake, your production environment is safe.

What else can be customized? Obviously you can configure the staging, Jenkins, and production development environments for different databases, or even for different hosts. Then adjust those configurations in each of the environment configuration files.
Use these configurations

Regardless of which method you usually use, these configurations are easy to use. To use the operating system's environment, you only have to do this:

Export django_settings_module= "Foo.settings.jenkins"

Now you are using the Jenkins configuration.

Or maybe you prefer to use them as such command-line options:

./manage.py Migrate-settings=foo.settings.production

Similarly, if you use Gunicorn, the command is as follows:

Gunicorn-w 4-b 127.0.0.1:8001-settings=foo.settings.dev

What other customizable configurations are there?

Another practical suggestion is to change some of the default collection configurations from tuples to lists. For example, Installed_apps it from:

Installed_apps = (
...
..) )

To

Installed_apps = [
  ...
]

Now, based on specific profiles for each environment, we can more easily add and remove applications from foo/settings/base.py files. For example, you might want to install the Django Debugging toolbar only in the dev environment rather than in other environments.

This technique is also useful for template_dirs and middleware_classes configurations.

Another technique that we often use is to divide the application into two lists, one that is necessary for the project and the other for actual project applications. As shown in the following:

Prereq_apps = [
  ' Django.contrib.auth ',
  ' django.contrib.contenttypes ',
  ...
  ' Debug_toolbar ',
  ' Imagekit ',
  ' haystack ',
]
 
Project_apps = [
  ' homepage ',
  ' users ',
  ' blog ',
]
 
Installed_apps = Prereq_apps + Project_apps

Why is this useful? First, it helps to better differentiate between Django core applications, Third-party applications, and specific applications of your own internal projects. For things like testing and code coverage, it's often useful to include a project_apps list of your specific applications. You have a list of applications to write, so you can easily and automatically make sure that their tests run, that the test coverage of the records includes only them without any third-party applications, and that you do not need to maintain the list in two different places.
Modify Requirements

Most of the items have a requirements.txt file, which is installed with the following command:

Pip Install-r requirements.txt

For simple small projects This is enough, but the Requirements.txt file has a little-known feature that you can use the-R parameter to include other files. So, for all the common installation requirements, we can create a base.txt file; Then, if we need to be able to run the tests, we can create a specific requirements/test.txt file that contains the following:

Copy Code code as follows:
-R Base.txt
pytest==2.5.2
coverage==3.7.1

I admit that there is no great benefit, but it does help to differentiate between what is required for each development environment. At the same time, for its performance, it does not install a bunch of things that are not in actual production, to reduce the PIP installation time in the production environment.
Test Files

Why do we have to split a large test file? One of the main reasons is that if you write enough tests for each application in a tests.py file, the file will eventually become bloated. Such code is poorly readable, and you have to spend a lot of time in the editor scrolling through the code.

When you work with other developers, small files can also allow you to encounter fewer conflicts when code is merged. Small files are your friends.
URLs

For small projects, put all the URL definitions in the foo/urls.py file and keep them in the same place. However, if your goal is clear and reusable code, you might want to define their URLs in each application and then include them in your main project. You should not do the following:

Urlpatterns = Patterns (',
  url (r ' ^$ ', Homepageview.as_view (), name= ' home '),
  url (r ' ^blog/$ ', Bloglist.as_ View (), name= ' blog_list '),
  url (r ' ^blog/? p<pk>d+)/$ ', Blogdetail.as_view (), name= ' Blog_detail '),
  ...
  URL (r ' ^user/list/$ ', Userlist.as_view (), name= ' user_list '),
  url (r ' ^user/(?) p<username>w+)/$ ', Userdetail.as_view (), name= ' User_detail '),

You should do this:

Urlpatterns = Patterns (',
  url (r ' ^$ ', Homepageview.as_view (), name= ' home '),
  url (r ' ^blog/', include (' Blog.urls ')),
  URL (r ' ^user/', include (' User.urls ')),

Templates and Static resources

There are templates/and static/directories in each application, which allows an application to be largely reused in other projects.

For a cool feature, we are all in a package to get the application provided by the default template and any related static resources, such as special JavaScript.

However, it also allows us to overwrite the template under foo/templates/for each project's home directory. We overwrite the default blog/templates/blog/detail.html template by adding a templates/blog/detail.html template.
re-use Django application

Assuming you've been using this layout for a while, one day you'll realize that your new project needs a blog application, and this application from your Foo project will be perfect. So you copy, paste the file ... Error! Now you have two copies of this application. Suppose you remember that a bug fix and a new feature addition in one replica need to be migrated manually between projects.

Instead, create a new directory for your blog and put the contents of the foo/blog/directory in it. Also, adjust the existing Foo project and your new project to install it.

If needed, they can still track the applications of these two different versions, or continue to update them, and get all the bug fixes and new features that are evolving. You can still overwrite templates and static resources on a per-project basis, so there's really no problem with that.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.