Django:修订间差异

无编辑摘要
 
(未显示同一用户的19个中间版本)
第13行: 第13行:
|[https://docs.djangoproject.com/zh-hans/3.2/topics/install/ Django 文档:如何安装 Django]
|[https://docs.djangoproject.com/zh-hans/3.2/topics/install/ Django 文档:如何安装 Django]
}}
}}
==基础知识==
==快速入门==
=== 架构 ===
=== 架构 ===
{{#drawio:Django架构}}
{{#drawio:Django架构}}
第20行: 第20行:
====创建项目====
====创建项目====
打开命令行,cd 到一个你想放置你代码的目录,然后运行以下命令:
打开命令行,cd 到一个你想放置你代码的目录,然后运行以下命令:
django-admin startproject mysite
<syntaxhighlight lang="bash" >
django-admin startproject mysite
 
# 在当前目录下初始化mysite app,而不是再创建一个mysite目录
# django-admin startproject mysite .
</syntaxhighlight>


{{了解更多
{{了解更多
第40行: 第45行:
|[https://docs.djangoproject.com/zh-hans/3.2/intro/tutorial01/#the-development-server Django 文档:用于开发的简易服务器]
|[https://docs.djangoproject.com/zh-hans/3.2/intro/tutorial01/#the-development-server Django 文档:用于开发的简易服务器]
}}
}}
===启动关闭脚本===
启动脚本,程序后台运行,关闭终端也不会停止。
<syntaxhighlight lang="bash" >
#!/bin/bash
logfile=django.log  #设置日志文件
source env/bin/activate  # 激活虚拟环境
# 后台运行
nohup python manage.py runserver 8002>$logfile 2>&1 &
tail -f $logfile  #监控日志
</syntaxhighlight>
关闭脚本,即关闭相应端口的程序,可以使用命令<code>kill $(lsof -t -i:8002)</code>,也可以写成脚本:
<syntaxhighlight lang="bash" >
port=8002
pid=$(lsof -t -i:$port)
if [ ! -z "$pid" ]; then
  kill $pid
  echo "端口$port被占用, 结束进程$pid。" 
else
  echo "端口$port未使用。"
fi
</syntaxhighlight>


==URL 路由==
==URL 路由==
第53行: 第81行:
}}
}}
==模板==
==模板==
=== 变量 ===


=== 内置模板标签 ===
=== 标签 ===
{| class="wikitable"  style="width: 100%;
{| class="wikitable"  style="width: 100%;
! 标签
! 标签
! 写法
! 描述
! 描述
! 示例
! 示例
|-
|-
| [https://docs.djangoproject.com/zh-hans/3.2/ref/templates/builtins/#block block]
| if
|<syntaxhighlight lang="django" >
|  
{% block 块名称 %}
|
...
|-
{% endblock 块名称 %}
| for
</syntaxhighlight>
|  
| 定义一个可以被子模板覆盖的块。更多信息请参见 [https://docs.djangoproject.com/zh-hans/3.2/ref/templates/language/#template-inheritance 模板继承]。
|  
|  
|-
|-
| include
| include
| 嵌入一个模板。
|  
|  
|-
| extends
| 该模板继承了一个父模板。 两种写法: <br /> <code>{% extends "base.html" %} </code> <br />
|  
|  
|-
| [https://docs.djangoproject.com/zh-hans/3.2/ref/templates/builtins/#block block]
| <syntaxhighlight lang="django" >
{% block 块名称 %}
...
{% endblock 块名称 %}
</syntaxhighlight>  定义一个可以被子模板覆盖的块。更多信息请参见 [https://docs.djangoproject.com/zh-hans/3.2/ref/templates/language/#template-inheritance 模板继承]。
|  
|  
|-
|-
| url
| url
|
|  
|  
|  
|  
第84行: 第121行:
|[https://docs.djangoproject.com/zh-hans/3.2/ref/templates/builtins/ Django 文档:内置模板标签和过滤器]
|[https://docs.djangoproject.com/zh-hans/3.2/ref/templates/builtins/ Django 文档:内置模板标签和过滤器]
|}}
|}}
=== 内置过滤器 ===
 
=== 过滤器 ===
内置过滤器
{| class="wikitable"  style="width: 100%;
{| class="wikitable"  style="width: 100%;
! 过滤器
! 过滤器
第124行: 第163行:
}}
}}


===创建模型===
===快速上手===
创建一个模型即创建一个表。每个模型都是一个 Python 的类,这些类继承 django.db.models.Model。
==== 配置数据库 ====
 
==== 定义模型 ====
创建一个模型即创建一个表。每个模型都是一个 Python 的类,这些类继承 django.db.models.Model。如定义了一个 Photo模型,拥有title、image 和 upload_time字段 :
<syntaxhighlight lang="python" >
# 创建app:python manage.py startapp testapp,
# 位于 testapp/models.py
from django.db import models
 
class Photo(models.Model):
    title = models.CharField('照片标题', max_length=50)
    image = models.ImageField(upload_to='photo/%Y%m%d/')
    upload_time = models.DateTimeField(default=now)
 
    def __str__(self):
        return self.image.name
 
    class Meta:
        ordering = ('-upload_time',)
</syntaxhighlight>
 
==== 注册app ====
需要将app名称加入到配置文件settings.py的INSTALLED_APPS。
<syntaxhighlight lang="python" >
INSTALLED_APPS = [
    # ...
    "testapp",
    # ...
]
</syntaxhighlight>
==== 数据迁移 ====
创建迁移文件:<code>python manage.py makemigrations testapp</code>。会在testapp/migrations创建一个将要执行的操作,如0001_initial.py <br />
执行迁移:<code>python manage.py migrate testapp</code>,将迁移文件的建表或修改表应用到数据库上。
 
==== 增删改查 ====
 
===迁移===
{| class="wikitable"
|-
! 命令
! 描述
! 示例
|-
| makemigrations
| 基于模型的修改创建迁移。
| <code>python manage.py makemigrations testapp</code>创建testapp所有模型的迁移文件
|-
| migrate
| 应用和撤销迁移。注意回滚迁移,可能会造成数据丢失。
|<code>python manage.py migrate testapp</code>应用迁移 <br /><code>python manage.py migrate testapp 0001</code>将数据库模式调整到适用指定迁移的状态。 <br /><code>python manage.py migrate testapp zero</code>撤销所有迁移,到最初状态。
|-
| sqlmigrate
| 显示迁移使用的SQL语句。
| <code>python manage.py sqlmigrate testapp 0001</code>显示迁移文件的SQL语句 testapp/migrations/0001_initial.py
|-
| showmigrations
| 显示迁移文件和迁移状态。
| <code>python manage.py showmigrations testapp</code> <br /><code>python manage.py showmigrations</code>
|}
{{了解更多
|[https://docs.djangoproject.com/zh-hans/4.2/topics/migrations/ Django 文档:迁移]
}}
 
===模型字段===
====字段类型====
 
====模型关联====
{| class="wikitable"
! 名称
! 描述
! 示例
|-
| 多对一关联 <br /><code>ForeignKey</code>
|
|
|-
| 多对多关联 <br /><code>ManyToManyField</code>
|
|
|-
| 一对一关联 <br /><code> OneToOneField</code>
|
|
|}
 
{{了解更多
|[https://docs.djangoproject.com/zh-hans/4.2/topics/db/examples/  Django文档:模型关联 API 用法示例]
}}
 
==表单==
===常用表单类===
{| class="wikitable"
! 名称
! 描述
|-
| Form
| 最基础的表单。示例:<syntaxhighlight lang="python" >
from django import forms
 
class NameForm(forms.Form):
    your_name = forms.CharField(label="你的名字", max_length=100)
</syntaxhighlight>
|-
| ModelForm
| 一个模型的表单。是在Form的基础上,与模型关联,简化操作。示例:
<syntaxhighlight lang="python" >
from django.forms import ModelForm
from myapp.models import Order
 
class OrderForm(ModelForm):
    class Meta:
        model = Order
        fields = ["order_date", "customer"]
</syntaxhighlight>
|-
| FormSet
| 一组Form的集合,用于处理提交多个相同类型的数据。使用<code>formset_factory()</code>创建。
|-
| ModelFormSet
| 一组ModelForm的集合,用于处理提交多个模型实例数据。使用<code>modelformset_factory()</code>创建。
|-
| InlineFormSet
| 用于关联模型创建表单集,通常用于处理一对多关系。使用<code>inlineformset_factory()</code>创建。<br />示例,Order账单模型和OrderDetail账单明细模型:<syntaxhighlight lang="python" >
from django import forms
 
OrderDetailFormset = forms.inlineformset_factory(Order, OrderDetail, form=OrderDetailForm, extra=1)
</syntaxhighlight>
|}


==日志==
==日志==
第162行: 第328行:
|-
|-
| [https://docs.djangoproject.com/zh-hans/3.2/topics/logging/#loggers Loggers]
| [https://docs.djangoproject.com/zh-hans/3.2/topics/logging/#loggers Loggers]
| '''日志系统的入口'''<br /> 由一个或多个logger组成,每个logger都是由名称和logger配置项组成。<br /><br />logger参数:<br /><code>level</code> 配置日志级别,可选值:DEBUG:排查故障时使用的低级别系统信息。INFO:一般的系统信息。WARNING:描述系统发生了一些小问题的信息。ERROR:描述系统发生了大问题的信息。CRITICAL:描述系统发生严重问题的信息。<br /><code>handlers</code> 配置使用的handler列表,如'handlers': ['handler1', 'handler2']。
| '''日志系统的入口'''<br /> 由一个或多个logger组成,每个logger都是由名称和logger配置项组成。<br /><br />logger参数:<br /><code>level</code> 配置日志级别,可选值:<br />DEBUG:排查故障时使用的低级别系统信息。<br />INFO:一般的系统信息。<br />WARNING:描述系统发生了一些小问题的信息。<br />ERROR:描述系统发生了大问题的信息。<br />CRITICAL:描述系统发生严重问题的信息。<br /><code>handlers</code> 配置使用的handler列表,如'handlers': ['handler1', 'handler2']。
|<syntaxhighlight lang="python">
|<syntaxhighlight lang="python">
'loggers': {
'loggers': {
第189行: 第355行:
|[https://docs.djangoproject.com/zh-hans/3.2/topics/logging/ Django 文档:日志]
|[https://docs.djangoproject.com/zh-hans/3.2/topics/logging/ Django 文档:日志]
}}
}}
==生产部署==
=== 生产开发的settings ===
在 Django 项目中,通常会为开发环境和生产环境分别配置不同的 settings 文件,以确保在不同环境中有适当的配置。常见做法:使用 settings/dev.py 和 settings/prod.py 文件分别用于开发和生产环境,而 settings/base.py 文件包含共享的基本配置。
<syntaxhighlight lang="text" >
my_project/
|-- my_project/
|  |-- settings/
|      |-- __init__.py
|      |-- base.py
|      |-- dev.py
|      |-- prod.py
|-- manage.py
|-- ...
</syntaxhighlight>
base.py的内容('''注意:BASE_DIR最后要多加一个.parent'''):
<syntaxhighlight lang="python" >
# my_project/settings/base.py
from pathlib import Path
# BASE_DIR最后要多加一个.parent
BASE_DIR = Path(__file__).resolve().parent.parent.parent
SECRET_KEY = 'your_secret_key'
DEBUG = False
ALLOWED_HOSTS = []
# ... 其他共享配置 ...
</syntaxhighlight>
dev.py的内容:
<syntaxhighlight lang="python" >
# my_project/settings/dev.py
from .base import *
DEBUG = True
# 开发环境数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
# 其他开发环境特有的配置
</syntaxhighlight>
prod.py的内容:
<syntaxhighlight lang="python" >
# my_project/settings/prod.py
from .base import *
DEBUG = False
SECRET_KEY = 'your_production_secret_key'
ALLOWED_HOSTS = ['example.com']
# 4.0后,DEBUG = False时不添加CSRF_TRUSTED_ORIGINS,
# POST时会出现错误:禁止访问 (403) CSRF验证失败. 请求被中断.
CSRF_TRUSTED_ORIGINS = ['https://example.com','https://www.example.com',]
# 生产环境数据库配置,例如使用 PostgreSQL
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'your_production_db_name',
        'USER': 'your_production_db_user',
        'PASSWORD': 'your_production_db_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}
# 其他生产环境特有的配置
</syntaxhighlight>
在修改manage.py,设置默认配置
<syntaxhighlight lang="python" >
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_project.settings.dev')
</syntaxhighlight>
在电脑设置环境变量`DJANGO_SETTINGS_MODULE`来指定使用哪个配置文件。
<syntaxhighlight lang="bash" >
# 在 windows上
set DJANGO_SETTINGS_MODULE=my_project.settings.dev
# 在 Linux 或 macOS 上
export DJANGO_SETTINGS_MODULE=my_project.settings.dev
</syntaxhighlight>
==安全==
==资源==
==资源==
===官网===
===官网===

2024年5月2日 (四) 06:59的最新版本

Django是一个开源的Web应用框架,使用Python编程语言写成。采用了MVT的软件设计模式,即模型(Model),视图(View)和模板(Template)。Django的主要目标是简化数据库驱动的网站的开发。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don't Repeat Yourself)。

简介

时间轴

  • 2005年7月21日,使用BSD许可证发布。
  • 2008年6月17日,Django成立基金会。

安装

使用pip安装:

pip install Django

了解更多 >> Django 文档:如何安装 Django


快速入门

架构

drawio: Django架构

第一个 Django 应用

创建项目

打开命令行,cd 到一个你想放置你代码的目录,然后运行以下命令:

django-admin startproject mysite

# 在当前目录下初始化mysite app,而不是再创建一个mysite目录
# django-admin startproject mysite .

了解更多 >> Django 文档:创建项目


启动简易服务器

打开命令行,cd进入到manage.py所在目录,然后运行以下命令:

python manage.py runserver

#默认监听本机内部 IP 的 8000 端口,也可以指定其他,如8002端口:
python manage.py runserver 8002

现在已经启动了Django 自带的用于开发的简易服务器。浏览器访问 https://127.0.0.1:8002/ ,就可以看到“祝贺”页面。

了解更多 >> Django 文档:用于开发的简易服务器


启动关闭脚本

启动脚本,程序后台运行,关闭终端也不会停止。

#!/bin/bash
logfile=django.log   #设置日志文件
source env/bin/activate  # 激活虚拟环境
# 后台运行
nohup python manage.py runserver 8002>$logfile 2>&1 &
tail -f $logfile  #监控日志

关闭脚本,即关闭相应端口的程序,可以使用命令kill $(lsof -t -i:8002),也可以写成脚本:

port=8002
pid=$(lsof -t -i:$port)

if [ ! -z "$pid" ]; then
  kill $pid
  echo "端口$port被占用, 结束进程$pid。"  
else
  echo "端口$port未使用。"
fi

URL 路由

URL路由在urls.py文件中配置,URL模式到视图函数的简单映射。

了解更多 >> Django 文档:URL调度器


视图函数

视图函数接收Web 请求并返回一个 Web 响应,这个响应可以是任何内容,如HTML内容、图片、重定向、404错误等。

了解更多 >> Django 文档:编写视图


模板

变量

标签

标签 描述 示例
if
for
include 嵌入一个模板。
extends 该模板继承了一个父模板。 两种写法:
{% extends "base.html" %}
block
{% block 块名称 %}
...
{% endblock 块名称 %}
定义一个可以被子模板覆盖的块。更多信息请参见 模板继承
url

了解更多 >> Django 文档:内置模板标签和过滤器


过滤器

内置过滤器

过滤器 描述 示例
add 变量加上参数值。这个过滤器将首先尝试将两个值强制转为整数。 {{ value|add:2}} value的值加2
{{ value1|add:value2 }}value1加value2值。

了解更多 >> Django 文档:内置模板标签和过滤器


数据模型

概览

Django提供了ORM功能,能更方便管理数据库。对象关系映射Object-Relational Mapping(ORM),是使用面向对象的方式操作数据库,映射关系如下:

数据库 编程语言
表(table) 类(class)
记录(record)或称行 对象(object)
字段(field)或称列 对象的属性(attribute)

了解更多 >> Django 文档:模型和数据库


快速上手

配置数据库

定义模型

创建一个模型即创建一个表。每个模型都是一个 Python 的类,这些类继承 django.db.models.Model。如定义了一个 Photo模型,拥有title、image 和 upload_time字段 :

# 创建app:python manage.py startapp testapp, 
# 位于 testapp/models.py 
from django.db import models

class Photo(models.Model):
    title = models.CharField('照片标题', max_length=50)
    image = models.ImageField(upload_to='photo/%Y%m%d/')
    upload_time = models.DateTimeField(default=now)

    def __str__(self):
        return self.image.name

    class Meta:
        ordering = ('-upload_time',)

注册app

需要将app名称加入到配置文件settings.py的INSTALLED_APPS。

INSTALLED_APPS = [
    # ...
    "testapp",
    # ...
]

数据迁移

创建迁移文件:python manage.py makemigrations testapp。会在testapp/migrations创建一个将要执行的操作,如0001_initial.py
执行迁移:python manage.py migrate testapp,将迁移文件的建表或修改表应用到数据库上。

增删改查

迁移

命令 描述 示例
makemigrations 基于模型的修改创建迁移。 python manage.py makemigrations testapp创建testapp所有模型的迁移文件
migrate 应用和撤销迁移。注意回滚迁移,可能会造成数据丢失。 python manage.py migrate testapp应用迁移
python manage.py migrate testapp 0001将数据库模式调整到适用指定迁移的状态。
python manage.py migrate testapp zero撤销所有迁移,到最初状态。
sqlmigrate 显示迁移使用的SQL语句。 python manage.py sqlmigrate testapp 0001显示迁移文件的SQL语句 testapp/migrations/0001_initial.py
showmigrations 显示迁移文件和迁移状态。 python manage.py showmigrations testapp
python manage.py showmigrations

了解更多 >> Django 文档:迁移


模型字段

字段类型

模型关联

名称 描述 示例
多对一关联
ForeignKey
多对多关联
ManyToManyField
一对一关联
OneToOneField

了解更多 >> Django文档:模型关联 API 用法示例


表单

常用表单类

名称 描述
Form 最基础的表单。示例:
from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label="你的名字", max_length=100)
ModelForm 一个模型的表单。是在Form的基础上,与模型关联,简化操作。示例:
from django.forms import ModelForm
from myapp.models import Order

class OrderForm(ModelForm):
    class Meta:
        model = Order
        fields = ["order_date", "customer"]
FormSet 一组Form的集合,用于处理提交多个相同类型的数据。使用formset_factory()创建。
ModelFormSet 一组ModelForm的集合,用于处理提交多个模型实例数据。使用modelformset_factory()创建。
InlineFormSet 用于关联模型创建表单集,通常用于处理一对多关系。使用inlineformset_factory()创建。
示例,Order账单模型和OrderDetail账单明细模型:
from django import forms

OrderDetailFormset = forms.inlineformset_factory(Order, OrderDetail, form=OrderDetailForm, extra=1)

日志

概览

Django 使用 Python 内置的 logging 模块处理系统日志。将下面一个简单的日志配置放入settings.py中,它将所有来自 django 命名的记录器的日志记录写入本地文件。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/path/to/django/debug.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

了解更多 >> Django 文档:日志


日志配置

名称 描述 示例
Loggers 日志系统的入口
由一个或多个logger组成,每个logger都是由名称和logger配置项组成。

logger参数:
level 配置日志级别,可选值:
DEBUG:排查故障时使用的低级别系统信息。
INFO:一般的系统信息。
WARNING:描述系统发生了一些小问题的信息。
ERROR:描述系统发生了大问题的信息。
CRITICAL:描述系统发生严重问题的信息。
handlers 配置使用的handler列表,如'handlers': ['handler1', 'handler2']。
'loggers': {
    'django': {
        'handlers': ['file'],
        'level': 'DEBUG',
        'propagate': True,
    },
},
Handlers 处理logger消息
配置消息输出位置,屏幕、文件或网络 socket。和 logger 一样,handler 也有日志级别的概念。
filters 过滤器
在日志记录从 logger 传到 handler 的过程中,使用 Filter 来做额外的控制。
Formatters 文本的格式
将日志记录文本按特定格式组织。

了解更多 >> Django 文档:日志


生产部署

生产开发的settings

在 Django 项目中,通常会为开发环境和生产环境分别配置不同的 settings 文件,以确保在不同环境中有适当的配置。常见做法:使用 settings/dev.py 和 settings/prod.py 文件分别用于开发和生产环境,而 settings/base.py 文件包含共享的基本配置。

my_project/
|-- my_project/
|   |-- settings/
|       |-- __init__.py
|       |-- base.py
|       |-- dev.py
|       |-- prod.py
|-- manage.py
|-- ...

base.py的内容(注意:BASE_DIR最后要多加一个.parent):

# my_project/settings/base.py
from pathlib import Path

# BASE_DIR最后要多加一个.parent
BASE_DIR = Path(__file__).resolve().parent.parent.parent
SECRET_KEY = 'your_secret_key'
DEBUG = False
ALLOWED_HOSTS = []
# ... 其他共享配置 ...

dev.py的内容:

# my_project/settings/dev.py
from .base import *

DEBUG = True
# 开发环境数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
# 其他开发环境特有的配置

prod.py的内容:

# my_project/settings/prod.py
from .base import *

DEBUG = False
SECRET_KEY = 'your_production_secret_key'
ALLOWED_HOSTS = ['example.com']
# 4.0后,DEBUG = False时不添加CSRF_TRUSTED_ORIGINS,
# POST时会出现错误:禁止访问 (403) CSRF验证失败. 请求被中断.
CSRF_TRUSTED_ORIGINS = ['https://example.com','https://www.example.com',]
# 生产环境数据库配置,例如使用 PostgreSQL
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'your_production_db_name',
        'USER': 'your_production_db_user',
        'PASSWORD': 'your_production_db_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}
# 其他生产环境特有的配置

在修改manage.py,设置默认配置

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_project.settings.dev')

在电脑设置环境变量`DJANGO_SETTINGS_MODULE`来指定使用哪个配置文件。

# 在 windows上
set DJANGO_SETTINGS_MODULE=my_project.settings.dev

# 在 Linux 或 macOS 上
export DJANGO_SETTINGS_MODULE=my_project.settings.dev

安全

资源

官网

相关教程

相关文章