Django 学习笔记

| 热度 | 字数统计: 2,095 字 | 阅读时长: 10 分

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

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

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

顺便吐槽下国内的的 X客园, Xsdn Xteye 等等网站, 内容复制来复制去的就不说什么了, 关于 Django 和 Python 深入一点的问题完全答非所问, 最后只好在 Django Python 官方文档和 StackOverFlow 找到答案.

版本

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 :P

视图

视图在 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

本文标题:Django 学习笔记

文章作者:X1r0z

发布时间:2018年08月28日

原始链接:https://exp10it.cn/2018/08/28/2018-08-28-django-study-note/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者.