Skip to content

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}))

模板

模板处理分为两过程:

  1. 加载HTML
  2. 渲染数据

模板主要有两个部分:

  1. HTML静态代码
  2. 动态插入的代码段(挖坑、填坑)

模板中的变量

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:浮点数。
  • BooleanFieldTrue/False。此字段表单控件是 checkboxinput
  • DateField:使用 Python 的 datetime.date 表示的时间。参数 auto_now,每次保存对象时,自动设置该字段为当前时间, 用于最后一次修改的时间戳,默认 Falseauto_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/ 输入账号密码进入后台,可以看到刚创建的模型:

Alt text

但是数据展示的方式不好,可以对模型添加魔术方法 __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}'

可以看到数据展示方式变为了设计好的格式:

Alt text