Some suggestions for Python's Django framework Deployment

Source: Internet
Author: User
"What is the best layout for Django Apps, profiles, and various other related catalogs?" ”

There are always friends asking us this question, so I would like to take a moment to write about how we look at the problem, so that we can easily get others to refer to this 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 version 1.4.

While 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 app for other projects. This is usually unclear, just as you are building an app that is reusable, whether or not it is to be reused. Building your app in the first way you want to reuse it makes it all easier.
    2. Encourage the design of reusable applications.
    3. Detailed settings for the environment. In a single overall configuration file, the If Debug==true does not make any sense. This makes it easy to see which configurations are shared and which are writable on a per-environment basis.
    4. Specific installation requirements for the environment (PIP requirements).
    5. If necessary, the project-level templates and static files can overwrite the application-level default values.
    6. Smaller and more specific test files are easier to read and understand.

Let's say you have two app blogs and users, and two dev environments and prod. The layout structure of your project should look like this:
Copy the 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 invoke the example Project Foo, and I know it's a very creative name. Let's assume here we're going to start foo.com. But when we want to map our project name to the final domain name, the project will exist here in a way that does not require any meaning.

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    wsgi.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 code control system (such as Git).

You should think of the sub-directory foo/foo/is this project. All the files here, not a Django application, are the companion files associated with the project.
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 few people know this might even happen. 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 under the foo/foo/directory, creating an empty __init __.py file inside.
Move the foo/foo/settings.py 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 file for these four environments should contain the following:

  From base Import *

Why is this important? For local development you want to set up debug=true, but it is easy to accidentally push this into 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 development environments such as staging, Jenkins, and production for different databases and even different hosts. You can then adjust those configurations in each environment configuration file.
Use these configurations

Regardless of which method you typically use, these configurations are easy to use. To use the operating system environment, you just have to do:

Export django_settings_module= "Foo.settings.jenkins"

Now you're using Jenkins's configuration.

Alternatively, you might 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 else can I customize?

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

Installed_apps = (... )

Switch

Installed_apps = [  ...]

Now, based on specific profiles for each environment, we can more easily add and remove apps from the foo/settings/base.py file. For example, you might want to install the Django Debugging toolbar only in the dev environment, not in another environment.

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 the actual project application. As shown in the following:

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

Why is this useful? First, it helps to better differentiate the specific applications of Django core applications, third-party applications, and your own internal projects. For things like testing and code coverage, it's often useful to write down a list of Project_apps for your particular application. You have a list of applications, so you can easily and automatically ensure that their test runs, and that the recorded test coverage only includes them without any third-party apps, and does not need to maintain the list in two different places.
Modify Requirements

Most projects 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. Therefore, for all common installation requirements, we can create a base.txt file, and 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 the 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 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 used in actual production to reduce PIP installation time in a production environment.
Test file

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 very bloated. This 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 also allow you to encounter fewer conflicts when your code is merged. The small file is your friend.
URLs

For small projects, place all of 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 app, 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
 
  
   
  d+)/$ ', Blogdetail.as_view (), name= ' Blog_detail '),  ...  URL (r ' ^user/list/$ ', Userlist.as_view (), name= ' user_list '),  url (r ' ^user/(? P
  
   
    
   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 basically reused in other projects.

For a cool feature, we get all the default templates and any related static resources, such as special JavaScript, in one package that the app provides.

However, it also allows us to overwrite the template under the home directory foo/templates/for each project. We overwrite the default blog/templates/blog/detail.html template by adding a templates/blog/detail.html template.
Reusing Django Applications

Assuming you've used this layout for a while, one day you'll realize that your new project needs a blog app, and this app from your Foo project will be perfect. So you copy, paste the file ... Error! Now you have two copies of this app. Suppose you remember that bug fixes and new additions in one copy need to be manually migrated 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.

If needed, they can still track these two different versions of the app, or keep updating them, and get all the bug fixes and new features they're constantly developing. You can still overwrite templates and static resources on a per-project basis, so there's really no problem with this.

  • Related Article

    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.