Django 快速入门

Django 是基于 Python 的 MVC 式 Web 框架.

与其它框架不同的是, Django 为 MVT 设计模式, M 为 Model, 负责对数据库结构的封装, V 为 View, 负责程序的主要操作, T 为 Template, 负责前端内容的输出.

不会讲太多, 文章面向那些想立即用 Django 快速开发一个网站/博客的朋友.

Django 不同的版本的语法和支持的环境几乎都有一些差异,例如路由的写法在 1.x 和 2.x 中就有很大区别.

目前常用的版本如下.

1
2
3
1.8.x: 支持 Python 2.7 3.2-3.5 LTS
1.11.x 支持 Python 2.7 3.4-3.6 LTS
2.0.x 支持 Python 3.4-3.7

我这里使用的是 1.11.x 版本.

创建项目.

django-admin startproject <PROJECT_NAME>

如果不出意外的话当前目录下会多出一个文件夹, 结构如下.

1
2
3
4
5
6
7
project
├── manage.py
└── project
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

manage.py 相当于当前项目下的 django-admin

settings.py 保存着项目的设置, urls.py 为路由规则, wsgi.py 在部署项目到生产环境的时候会用到.

再创建应用, 一个项目中会有多个应用存在.

manage.py startapp proj

应用结构.

1
2
3
4
5
6
7
8
9
proj
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

admin.py 配置 Django 后台的功能, apps.py 为当前应用的设置, migrations 文件夹保存数据库结构更改的记录.

models.py 为模型, views.py 为视图, test.py 一般不会用到.

先在项目的 settings.py 中加上当前 app 的名称.

1
2
3
4
INSTALLED_APPS = [
    ......
    'proj',
]

views.py 添加如下代码.

1
2
3
4
from django.shortcuts import HttpResponse

def index(request):
    return HttpResponse('<h1>helloworld</h1>')

最后配置路由.

1
2
3
4
5
6
7
8
from django.conf.urls import url
from django.contrib import admin
from proj import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.index),
]

启动服务器.

manage.py runserver

helloworld :)

视图在 views.py 中, 每一个函数对应着一个或多个操作.

1
2
def index(request):
  return HttpResponse('index')

request 相当于 PHP 中的 $_GET $_POST $_SESSION $_COOKIE$_SERVER 的集合

利用 request 接受各种参数.

1
2
3
request.GET.get('arg')
request.POST.get('form')
request.REQUEST.get('all')

获取和设置 cookie session.

1
2
3
4
request.COOKIES['a'] = 'b'
request.SESSION['c'] = 'd'
request.COOKIES.get('a')
request.SESSION.get('c')

获取客户端信息.

1
2
request.META.get('HTTP_USERAGENT')
request.META.get('REMOTE_ADDR')

其中还有像 request.GET['arg'] 这种方式获取数据, 不过数据不存在的时候会报错.

HttpResponse 返回 response.

HttpResponseRedirect 页面跳转.

路由在 urls.py 中, 1.11.x 使用正则表达式编写路由规则.

1
2
3
4
5
6
from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

urlpatterns 保存 url 对象, 实例化时传入正则和视图.

先引入当前 app 的包, 这样才能在路由中添加 app 中的视图函数.

各种路由.

1
2
url('^index', views.index)
url('^login', views.login)

去除末尾的斜杠.

1
2
url('^user/?', views.user)
url('^cart/?', views.cart)

pathinfo 风格传参.

1
url('^add/(.*)?/(.*)?', views.add)

视图函数.

1
2
def add(request,a,b):
    return HttpResponse(a+':'+b)

直接使用 HttpResponse 返回显得丑丑哒, django 使用 render 渲染模板.

在 app 目录下新建 templates 文件夹和 index.html

内容如下.

1
<h1> {{ message }} </h1>

views.py

1
2
def index(request):
    return render(request, 'index.html', {'message': 'helloworld'})

render 第一个参数默认为 request, 第二个为模板名称, 第三个为字典, 给模板传递内容.

django 的模板语法中, 使用两对大括号输出变量内容, 一对大括号和一对百分号进行 if for 等操作

各种模板.

if

1
2
3
4
5
6
7
8
9
{% if a > 5 %}
<strong> {{ a }} </storng>
{% endif %}

{% if islogin %}
<b> Welcome {{ name }} </b>
{% else %}
<b> Login
{% endif %}

for

1
2
3
4
5
6
7
8
<ul>
{% for a in list %}
<li> {{ forloop.counter }}.{{ a }} </li>
{% endfor %}
</ul>

{% for k,v in dict.items %}
<i>{{ k }}<i>: {{ v }}

模板还有过滤器, 如获取列表长度 list|length, 具体请到 Django 官方文档中查询.

模型在 models.py 中, 每一个 Class 对应着数据中的一张表, Class 的属性则为表中的字段.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from django.db import models

class User(models.Model):
    age = models.IntegerField()
    username = models.CharField(max_length=16)
    password = models.CharField(max_length=32)
    email = models.EmailField(max_length=32)
    blog = models.UrlField(max_length=32,blank=True)
    isguy = models.BooleanField(default=True)
    regtime = models.DateTimeField(auto_now_add=True)
    info = models.TextField(blank=True)

不同的 Field 存放不同类型的数据, IntegerField 为数字, CharField 为字符串, EmailField 为邮箱地址, UrlField 为 url, BooleanField 为布尔值, DateTimeField 为日期, TextField 为长文本.

Field 中还有不同的参数, max_length 为最大长度, blank 是否为空, default 指定默认值.

全部的 Field 以及可用的参数请到 Django 官方文档中查询.

操作数据的几种方式, 首先在 views.py 中引入 model.

from proj.models import User

推荐在 shell 中进行数据操作.

manage.py shell

查询.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Uer.objects.get(username='admin').age
res = Uer.objects.get(username='admin')
res.username

User.objects.filter(username='admin')
res = User.objects.filter(username='test')
res.filter(isguy=True)

res = User.objects.filter(username='123').first()
res.email

get 获取到的结果在一条以上时会报错, 而 filter 不会, 但 filter 获取只有一条数据的时候结构仍为 QuerySet (类似于 list), 需要指定 .first() 或者 .last() 才能像 get 一样进行操作.

插入.

1
2
3
4
5
6
7
8
9
User.objects.create(username='abc',password='abc')

user = User(username='abc',password='abc')
user.save()

user = User()
user.username = 'abc'
user.password = 'abc'
user.save()

更新.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
User.objects.filter(username='admin').update(isguy=True)

res = User.objects.filter(username='admin')
res.update(isguy=True)

user = User.objects.get(username='admin')
user.isguy = True
user.save()

User.objects.all().update(isguy=True)

删除.

1
2
3
4
5
6
User.objects.filter(username='admin').delete()

res = User.objects.filter(username='admin')
res.delete()

User.objects.all().delete()

切片.

1
2
3
User.objects.filter(age=1)[:10]

User.objects.all()[:5]

还有一些字段名加双下划线的表示特定条件的字段, 如 age__ltage__gt 表示 age 小于某数和 age 大于某数.

具体请到 Django 官方文档中查询.

后台在 admin.py 中, 路由默认为 ^admin/

创建后台用户.

mange.py createsuperuser

密码需大于 8 位.

默认的后台全是 Query Object 而且只显示一个字段, 需要手动修改下.

先在 models 中每一个 class 中加入如下内容.

1
2
def __unicode__(self):
  return self.username

3.x 为 __str__, 主要修改原在后台中显示的 Quert Object

修改 admin.py

1
2
3
4
5
6
7
from django.contrib import admin
from proj.models import User

class adminUser(admin.ModelAdmin):
	list_display = ('username', 'email', 'age', 'isguy', 'regtime')

admin.site.register(User, adminUser)

adminUser 类修改后台中显示的字段, 最后需要把 model 注册到 admin 中.

还有美化 添加功能等方面, 不过听说 django 默认的后台并不安全.

django 默认的项目 DEBUG 模式为 True, 这将导致路由 源码 异常等信息都会出现在客户端, 而且在生产环境下 django 的 runserver 的性能差的一批.

这里使用的是 nginx + uwsgi 方式进行项目的部署.

先在 settings.py 中设置 DEBUG = False

在项目目录下添加 uwsgi.ini

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[uwsgi]
socket = :8000
chdir = /home/exp10it/project
wsgi-file = /project/wsgi.py
module =bugscan.wsgi
master = true
processes = 4
vacuum = true
pidfile=uwsgi.pid
daemonize=uwsgi.log

启动.

uwsgi --ini uwsgi.ini

在 nginx 配置文件的 http 中加入如下内容.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
upstream django {
    server 127.0.0.1:8000;
}

server {
    listen  8082;

    location /static {
        alias /home/exp10it/project/static;
    }

    location / {
        uwsgi_pass django;
        include uwsgi_params;
    }
}

最后启动 nginx, 访问本机 8082 端口即可.

关于静态文件, 最好的方法就是像部署时 nginx 配置文件中的那样 alias.

至于用户的媒体文件, 在 app 目录中添加 media 文件并修改 settings.py 文件, 最后 nginx alias 即可.

django 默认的 csrf 防护需要在模板中添加 csrf_token, 不想使用的话可在 setting.pyMIDDLEWARE 中注释掉 django.middleware.csrf.CsrfViewMiddleware

django 的 cookie 默认 httponly.

django 的模板自带 xss filter.