夜间模式
Django
项目创建与运行
shell
pip install Django # 安装
python -m django --version # 查看版本号
django-admin startproject mysite # 创建项目
python manage.py runserver [ip:port] # 运行,默认 127.0.0.1:8000
项目创建后生成的目录:
txt
mysite/
manage.py # 用于管理项目的命令行工具,站点运行、数据库自动生成都通过本文件完成
mysite/
__init__.py
settings.py # 项目配置
urls.py # 路由
asgi.py # 和wsgi类似,但是能异步处理(类似Tornado异步框架)
wsgi.py # Web Server Gateway Interface, 即服务器网关接口,是Python应用和Web服务器之间的接口
项目的配置文件极为重要,部分配置的含义如下:
Python
BASE_DIR = Path(__file__).resolve().parent.parent # 根目录
DEBUG = True # 调试模式
ALLOWED_HOSTS = ['*'] # 允许访问的IP,'*'表示任意IP
MIDDLEWARE = ['django.middleware.common.CommonMiddleware'] # 中间件
ROOT_URLCONF = 'mysite.urls' # 根路由
STATIC_URL = 'static/' # 静态文件目录(CSS, JavaScript, Images)
# 定义应用
INSTALLED_APPS = [
'django.contrib.admin',
'myapp', # 定义自己的应用
]
数据迁移
迁移的概念:就是将模型映射到数据库的过程
生成迁移文件:python manage.py makemigrations
执行迁移:python manage.py migrate
创建应用
python manage.py startapp myapp
可以创建一个名为 myapp
的应用。
项目根目录下会多出一个文件夹:
txt
myapp/
__init__.py
admin.py
apps.py
migrations/
models.py # 添加模型层数据类文件
tests.py
views.py # 定义url相应函数(视图函数)
编写视图函数
在 views.py
中编写一个视图函数:
Python
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
return HttpResponse("<h1>Hello World</h1>")
# return render(request, 'index.html') # 或者编写一个HTML文件放置于/myapp/templates下
之后在 /mysite/urls.py
中添加路由:
Python
from myapp.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('myapp/', index)
]
访问 localhost:8000/myapp/
即可访问到视图函数响应的页面。
路由
除了像 上面的例子 那样直接在主路由文件中导入视图函数,还可以使用子路由。
使用子路由
在对应的应用下创建文件 /myapp/urls.py
,并书写子路由:
Python
from django.urls import path
from myapp.views import index # 导入视图函数
# 子路由
urlpatterns = [
path('home', index)
]
然后再去根路由 /mysite/urls.py
下通过 django.urls.include
导入:
Python
from django.urls import path, include
urlpatterns = [
path('myapp/', include('myapp.urls'))
]
此时访问 localhost:8000/myapp/home
即可见到视图函数响应的内容。
路由匹配
Python
# 给 url 视图函数传递参数,也能通过 name 取别名
path('detail/<int:user_id>', detail, name='detail')
# 视图函数可以接受路由上的参数
def detail(request, user_id: int):
return HttpResponse(user_id)
命名空间
每个应用都是自己的路由模块,为了防止路由冲突,Django 提供了命名空间(namespace)的概念,使得路由查询限定在该命名空间内。
Python
# 在根路由中可以设置命名空间
path('myapp/', include(('myapp.urls', 'myapp'), namespace='myapp'))
反向解析
通过反向解析,可以在代码中使用路由别名替代 URL 路径,提高可读性和可维护性。
Python
# 在视图函数中使用反向解析
from django.shortcuts import render, redirect, reverse
def view_func(request):
return redirect(reverse('index'))
# return redirect(reverse('detail', args=[2]))
# return redirect(reverse('detail', kwargs={'user_id': 2}))
模板
模板处理分为两过程:
- 加载HTML
- 渲染数据
模板主要有两个部分:
- HTML静态代码
- 动态插入的代码段(挖坑、填坑)
模板中的变量
Python
# 模板中的变量:视图传递给模板的数据、遵循标识符规则
{{ var }} # 如果变量不存在,则插入空字符串
# 使用方法时不能有参数
{{ str }}
{{ str.upper }}
{{ str.isdigit }}
{{ dict.keys }}
# 使用索引,不允许负索引
{{ list.2 }}
{{ list.0 }}
模板中的标签
Python
# if
{% if expr %}
...
{% else %}
...
{% endif %}
# for
{% for item in items %}
...
{% empty %} # 当列表为空或不存在时,执行下面代码块
...
{% endfor %}
{{ forloop.counter }} # 表示当前时第几次循环
{% for item in items %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
{{ forloop.counter0 }} # 表示当前时第几次循环,从 0 开始数
{{ forloop.revcounter }} # 表示当前时第几次循环,倒着数,[len, 1]
{{ forloop.revcounter0 }} # 表示当前时第几次循环,倒着数,[len - 1, 0]
{{ forloop.first }} # 是否是第一个,返回布尔值
{{ forloop.last }} # 是否是最后一个,返回布尔值
# 单行注释
{# 注释内容 #}
# 多行注释
{% comment %}
注释内容
{% endcomment %}
# 过滤器
{{ var | 过滤器 }} # 作用:在变量显示前修改
{{ value | add:2 }} # 加法过滤器,没有减法过滤器,可以通过加负数来实现减法
{{ str | lower }}
{{ my_list|first | upper }} # 选择第一个元素并大写
{{ str | truncatechars:30 }} # 截断
{{ my_list | join:',' }}
{{ value1 | default:value2 }} # 如果变量不存在或者为False、空,则使用默认值
# HTML转义
{{ code | safe }} # 渲染成HTML
# 关闭自动转义
{% autoescape off %}
{{ code }}
{% endautoescape %}
# 打开自动转义
{% autoescape on %}
{{ code }}
{% endautoescape %}
# 模板继承
# block:写在父模板中
{% block XXX %}
...
{% endblock %}
# extends:继承,写在开头位置
{% extends '父模板路径' %}
# include:加载模板进行渲染
{% include '模板文件' %}
模型
创建模型
创建自己的模型类,但是需要继承自 models.Model
。
Python
from django.db import models
# 模型 <==> 表结构
# 属性 <==> 表字段
# 对象 <==> 行数据
class UserModel(models.Model):
name = models.CharField(max_length=30, unique=True) # name VARCHAR(30) UNIQUE
age = models.IntegerField(default=18) # age INT DEFAULT 18
is_deleted = models.BooleanField(default=False) # is_deleted BOOL DEFAULT TRUE
创建模型之后,记得做数据迁移:
shell
python manage.py makemigrations # 生成迁移文件
python manage.py migrate # 执行迁移
字段类型
如果没有手动设置主键,Django 会为表添加自动增长的主键列,每个模型只能有一个主键列。
由于 Django 的查询方式,不允许使用连续的下划线命名字段。
常用字段类型:
AutoField
:一个自动增长的IntegerField
,通常不指定。如果不指定,Django 会自动添加一个 id 列。CharField
:字符串,默认表单样式为 input。TextField
:大文本字段,默认表单控件是 textarea。IntegerField
:整数。DecimalField
:浮点数。参数max_digits
表示总位数,decimal_places
表示小数的位数。FloatField
:浮点数。BooleanField
:True/False
。此字段表单控件是 checkboxinputDateField
:使用 Python 的datetime.date
表示的时间。参数auto_now
,每次保存对象时,自动设置该字段为当前时间, 用于最后一次修改的时间戳,默认False
,auto_now_add
,当对象被创建时自动设置时间,默认为False
。TimeField
:使用 Python 的datetime.time
表示的时间。参数同上。DateTimeField
:使用 Python 的datetime.datetime
表示的时间。参数同上。FileField
:一个上传文件的字段。ImageField
:继承了FileField
的所有属性和方法。但是要对上传的对象做校验,确保它是个有效的图片,需要安装 Pillow:pip install Pillow
。
常用字段参数:
null
:数据库中字段是否可以为空。blank
:Django 的 Admin 中添加数据是否允许为空值。一般null=True, blank=Ture
搭配使用。primary_key
:主键。auto_now
:自动更新操作时间。auto_now_add
:自动添加创建时间。choices
:后台 Admin 下拉菜单。例如:
Python
USER_TYPE_LIST = (
(1, '超级用户'),
(2, '普通用户'),
)
user_type = models.IntegerField(choices=USER_TYPE_LIST, default=1, verbose_name='用户类型')
max_length
:最大长度。default
:默认值。verbose_name
:后台管理中字段显示的名称。name|db_column
:数据库中的字段名称。unique
:字段值是否唯一。db_index
:数据库索引。editable
:在后台管理(Admin)中是否可编辑,不可编辑则不显示。
后台管理
在 admin.py
中将 model
加入后台管理:
Python
admin.site.register(UserModel)
创建超级用户:python manage.py createsuperuser
访问 localhost:8000/admin/
输入账号密码进入后台,可以看到刚创建的模型:
但是数据展示的方式不好,可以对模型添加魔术方法 __str__
:
Python
class UserModel(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField(default=18)
def __str__(self):
return f'{self.name} - {self.age}'
可以看到数据展示方式变为了设计好的格式: