Django advertises itself as "the web framework for perfectionists with deadlines" and "Django makes it easier to build better Web apps more quickly and with less code". It can be seen as an MVC architecture. At it's core it has:
| Version | Release Date |
|---|---|
| 1.11 | 2017-04-04 |
| 1.10 | 2016-08-01 |
| 1.9 | 2015-12-01 |
| 1.8 | 2015-04-01 |
| 1.7 | 2014-09-02 |
| 1.6 | 2013-11-06 |
| 1.5 | 2013-02-26 |
| 1.4 | 2012-03-23 |
| 1.3 | 2011-03-23 |
| 1.2 | 2010-05-17 |
| 1.1 | 2009-07-29 |
| 1.0 | 2008-09-03 |
Step 1 If you already have Django installed, you can skip this step.
pip install Django
Step 2 Create a new project
django-admin startproject hello
That will create a folder named hello which will contain the following files:
hello/
├── hello/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Step 3
Inside the hello module (the folder containing the __init.py__ ) create a file called views.py :
hello/
├── hello/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── views.py <- here
│ └── wsgi.py
└── manage.py
and put in the following content:
from django.http import HttpResponse
def hello(request):
return HttpResponse('Hello, World')
This is called a view function.
Step 4
Edit hello/urls.py as follows:
from django.conf.urls import url
from django.contrib import admin
from hello import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.hello)
]
which links the view function hello() to a URL.
Step 5 Start the server.
python manage.py runserver
Step 6
Browse to http://localhost:8000/ in a browser and you will see:
Hello, World
The default Django project template is fine but once you get to deploy your code and for example devops put their hands on the project things get messy. What you can do is separate your source code from the rest that is required to be in your repository.
You can find a usable Django project template on GitHub.
PROJECT_ROOT
├── devel.dockerfile
├── docker-compose.yml
├── nginx
│ └── project_name.conf
├── README.md
├── setup.py
└── src
├── manage.py
└── project_name
├── __init__.py
└── service
├── __init__.py
├── settings
│ ├── common.py
│ ├── development.py
│ ├── __init__.py
│ └── staging.py
├── urls.py
└── wsgi.py
I like to keep the service directory named service for every project thanks to that I can use the same Dockerfile across all my projects.
The split of requirements and settings are already well documented here:
Using multiple requirements files
Using multiple settings
With the assumption that only developers make use of Docker (not every dev ops trust it these days). This could be a dev environment devel.dockerfile :
FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /run/service
ADD . /run/service
WORKDIR /run/service
RUN pip install -U pip
RUN pip install -I -e .[develop] --process-dependency-links
WORKDIR /run/service/src
ENTRYPOINT ["python", "manage.py"]
CMD ["runserver", "0.0.0.0:8000"]
Adding only requirements will leverage Docker cache while building - you only need to rebuild on requirements change.
Docker compose comes in handy - especially when you have multiple services to run locally. docker-compose.yml :
version: '2'
services:
web:
build:
context: .
dockerfile: devel.dockerfile
volumes:
- "./src/{{ project_name }}:/run/service/src/{{ project_name }}"
- "./media:/run/service/media"
ports:
- "8000:8000"
depends_on:
- db
db:
image: mysql:5.6
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE={{ project_name }}
nginx:
image: nginx
ports:
- "80:80"
volumes:
- "./nginx:/etc/nginx/conf.d"
- "./media:/var/media"
depends_on:
- web
Your development environment should be as close to the prod environment as possible so I like using Nginx from the start. Here is an example nginx configuration file:
server {
listen 80;
client_max_body_size 4G;
keepalive_timeout 5;
location /media/ {
autoindex on;
alias /var/media/;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_pass http://web:8000/;
}
}
$ cd PROJECT_ROOT
$ docker-compose build web # build the image - first-time and after requirements change
$ docker-compose up # to run the project
$ docker-compose run --rm --service-ports --no-deps # to run the project - and be able to use PDB
$ docker-compose run --rm --no-deps <management_command> # to use other than runserver commands, like makemigrations
$ docker exec -ti web bash # For accessing django container shell, using it you will be inside /run/service directory, where you can run ./manage shell, or other stuff
$ docker-compose start # Starting docker containers
$ docker-compose stop # Stopping docker containers
django-admin is a command line tool that ships with Django. It comes with several useful commands for getting started with and managing a Django project.
The command is the same as ./manage.py , with the difference that you don't need to be in the project directory. The DJANGO_SETTINGS_MODULE environment variable needs to be set.
A Django project is a Python codebase that contains a Django settings file. A project can be created by the Django admin through the command django-admin startproject NAME . The project typically has a file called manage.py at the top level and a root URL file called urls.py . manage.py is a project specific version of django-admin , and lets you run management commands on that project. For example, to run your project locally, use python manage.py runserver . A project is made up of Django apps.
A Django app is a Python package that contains a models file (models.py by default) and other files such as app-specific urls and views. An app can be created through the command