Python Django 网站开发培训 - 2周入门 web后端开发 web服务端开发_哔哩哔哩_bilibili

千锋教育,接下来的笔记看的是这个

这个比较完整


Django快速入门


安装

使用 Virtualenvwrapper-win 创建和管理虚拟环境

在安装 Virtualenvwrapper-win 之后,你可以使用 mkvirtualenvworkon 来创建和管理虚拟环境。

1
pip install virtualenv virtualenvwrapper-win

查看虚拟环境

1
workon

创建虚拟环境

1
mkvirtualenv django4env

删除虚拟环境

1
rmvirtualenv django4env

激活虚拟环境

1
workon django4env
移植环境

将虚拟环境从一台机器转移到另一台机器,可以遵循以下步骤:

方法一:使用 requirements.txt

  1. 在源机器上生成依赖项文件

    • 激活虚拟环境,在终端中运行以下命令生成 requirements.txt 文件:
      1
      pip freeze > requirements.txt
  2. 复制项目代码和 requirements.txt 文件

    • 将整个项目目录以及生成的 requirements.txt 文件复制到目标机器上。
  3. 在目标机器上设置新的虚拟环境

    • 在目标机器上创建一个新的虚拟环境,例如:
      1
      python3 -m venv myenv
    • 激活新创建的虚拟环境:
      1
      source myenv/bin/activate
    • 使用 requirements.txt 文件安装依赖项:
      1
      pip install -r requirements.txt

方法二:直接复制整个虚拟环境

这种方法适用于目标和源机器具有相同的操作系统和 Python 版本。

  1. 复制整个虚拟环境目录

    • 找到虚拟环境的目录,通常在 .virtualenvs 或者 venv 目录下。可以通过激活虚拟环境后运行 which python 来定位。

    • 将整个虚拟环境目录复制到目标机器上。

  2. 调整路径

    • 如果虚拟环境的路径在目标机器上不同,那么需要在新机器上调整路径。
    • 具体地说,需要更新虚拟环境中 bin/activate 脚本以及 pyvenv.cfg 文件,将它们指向目标机器的路径。

设置镜像:
在命令提示符中执行以下命令:

1
set PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple

这个设置在当前命令提示符窗口会话期间有效。关闭窗口后,设置将会失效。

1
pip install django




初始化

  • 创建项目目录结构
1
django-admin startproject [项目名]

eg:

1
django-admin startproject myproject

结构如下:

1
2
3
4
5
6
7
8
9
myproject/
│ manage.py

└── myproject/
│ asgi.py
│ settings.py
│ urls.py
│ wsgi.py
└─ __init__.py
查看详细信息

以下是这些文件和目录的详细说明:

myproject/

这是 Django 项目的根目录。它包含项目的管理脚本 manage.py 和配置文件夹 myproject/

manage.py

  • 用途:这是一个用于管理 Django 项目的脚本。
  • 功能:提供一系列命令行选项,例如启动开发服务器、数据库迁移等。你可以通过 python manage.py <command> 来运行不同的管理命令。

myproject/(内部文件夹)

这个内部文件夹通常与项目根目录同名,包含项目的配置文件。

asgi.py

  • 用途:定义 ASGI 应用的入口。
  • 功能:在部署时提供 ASGI 兼容服务器加载 Django 项目的入口点,适用于处理异步任务。

settings.py

  • 用途:包含 Django 项目的配置设置。
  • 功能:包括数据库设置、模板配置、已安装的应用、调试选项等。你可以根据需要自定义这些设置。

urls.py

  • 用途:定义项目的 URL 路由配置。
  • 功能:将 URL 模式与视图函数或类匹配,以处理请求。主要用于 URL 到视图的映射。

wsgi.py

  • 用途:定义 WSGI 应用的入口。
  • 功能:为部署时的 WSGI 兼容服务器提供入口点。在生产环境中,它通常用于部署 Django 应用。

__init__.py

  • 用途:标记 myproject/ 文件夹为 Python 包。
  • 功能:使 Django 项目能够识别该文件夹是一个模块。


  • settings.py

注释详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""
Django settings for myproject project.

Generated by 'django-admin startproject' using Django 4.2.8.

For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from pathlib import Path

# 项目根目录,例如manage.py的位置,就是BASE_DIR / 'manage.py'
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# 项目的秘钥,不用动
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-j*+i0v^^k-!dath9g=qhy$6s$+!@k2mwl-&+gv!6mas2ct8s-6"

# 是否调试模式
# True: 表示调试模式,一般用于开发过程中
# False: 表示非调试模式,一般用于上线部署
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

# 被允许的域名或者ip
# * 表示所有
ALLOWED_HOSTS = ['*']


# Application definition
# 定义应用
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",

# 定义自己的应用,一定要记得写一下
]

# 中间件
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

# 根路由文件
ROOT_URLCONF = "myproject.urls"

# 模版
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]

# wsgi目录
WSGI_APPLICATION = "myproject.wsgi.application"


# Database 数据库,只能用关系型数据库
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}


# 密码验证
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]


# 国际化,一些语言配置
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = "en-us" # enus英语,zh-hans中文
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True

# 静态文件(css, javascript, images)
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = "static/"

# 默认主键字段的类型
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

ALLOWED_HOSTS 可以配置可用ip(默认127.0.0.1可用),含义就是 允许哪些ip访问服务器
eg: ALLOWED_HOSTS = ["49.140.60.13"]


问题一:时区修改

1
2
3
TIME_ZONE = "Asia/Shanghai"   # Asia/Shanghai UTC

USE_TZ = False

问题二:静态文件和媒体文件路径设置

1
2
3
4
5
6
7
8
9
# 静态文件
STATIC_URL = "/static/"
STATICFILES_DIRS = [
BASE_DIR / 'static'
]

# 媒体文件
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')


  • 运行服务器
1
python manage.py runserver [ip:端口]

eg:

1
python manage.py runserver 127.0.0.1:80

0.0.0.0 表示绑定本机所有的IP地址, 就是可以通过任何一个本机的IP (包括 环回地址 127.0.0.1 ) 都可以访问我们的服务。





数据迁移

概念: 就是将模型映射到数据库的过程

生成迁移文件:

1
python manage.py makemigrations

执行迁移:

1
python manage.py migrate

不需要初始化迁移文件夹,每个应用默认有迁移文件夹migrations

models表结构一旦改变就需要重新数据迁移





创建应用

  • 创建app命令
1
python manage.py startapp [app名]

创建完自己注册到settings.py

eg:

1
python manage.py startapp user 

文件结构:

1
2
3
4
5
6
7
8
9
10
user
│ admin.py
│ apps.py
│ models.py
│ tests.py
│ views.py
│ __init__.py

└─migrations
__init__.py

应用目录介绍:

  • __init__·py:
    其中暂无内容,使得app成为一个包
  • admin.py:
    管理站点模型的声明文件,默认为空
  • apps.py:
    应用信息定义文件,在其中生成了AppConfig,该类用于定义应用名等数据
  • models.py:
    添加模型层数据类文件
  • views.py:
    定义URL相应函数
  • migrations包:
    自动生成,生成迁移文件的
  • tests.py:
    测试代码文件




基本视图

其实就是对应 路由的处理函数(django叫视图函数)

例如:

url.py中修改为:

1
2
3
4
5
6
7
8
9
from django.contrib import admin
from django.urls import path

from user import views

urlpatterns = [
path("index/", views.index), # 不能加(), views.index()是错的
path("admin/", admin.site.urls),
]

view.py中为

1
2
3
4
5
6
7
8
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.

def index(request):
# 返回相应response#
return HttpResponse('Hello Django!')




Django框架流程

模版渲染不是一定需要的





路由

基本视图 小节已经展示了,这种称为直接路由

下面介绍一下 子路由

就是在对应app目录下面新建一个url.py,格式和配置目录的url.py保持一致,名字别写错了,所以直接复制即可

例如:

之前新建的app user添加url.py

1
2
3
4
5
6
from django.urls import path
from .views import index

urlpatterns = [
path('index/', index),
]

配置目录的url.py修改为:

1
2
3
4
5
6
7
8
9
from django.contrib import admin
from django.urls import path, include

import user

urlpatterns = [
path("user/", include('user.url')),
path("admin/", admin.site.urls),
]

最后通过https://ip:端口/user/index即可访问





基本模版

模板实际上就是我们用HTML写好的页面创建模板文件夹templates,在模板文件夹中创建模板文件

在views中去加载渲染模板,使用render函数:return render(request,'index.html')





定义模型

models.py中引入models

1
from django.db import models

创建自己的模型类,但切记要继承自 models.Model

案例驱动: 使用模型定义班级,并在模板上显示班级列表

user\models.py

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

# 模型Model -- 表结构
# 类属性 -- 表字段
# 对象 -- 表的一行记录

class UserModel(models.Model):
name = models.CharField(max_length=30, unique=True) # 对应sql:name varchar(30)
age = models.IntegerField(default=18) # 对应sql:age int(30) default
sex = models.CharField(max_length=20) # 对应sql:sex varchar(20)
is_deleted = models.BooleanField(default=False)

# 表结构一旦改变就需要重新数据迁移

没有主键会自动添加,执行完python manage.py migrate,可以在user\migrations\0001_initial.py看到id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Generated by Django 4.2.11 on 2024-05-01 18:30

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="UserModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=30, unique=True)),
("age", models.IntegerField(default=18)),
("sex", models.CharField(max_length=20)),
("is_deleted", models.BooleanField(default=False)),
],
),
]





模型的基本使用

上面已经数据迁移完成后,我们在数据表中添加两条数据:

之后我们在user包下新建目录templates,并在其中新建users.html文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户</title>
</head>
<body>
<h2>所有用户</h2>
<ul>
{% for user in users %}
<li>{{ user.name }},{{ user.age }}</li>
{% endfor %}
</ul>
</body>
</html>

view.py中编写视图函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.http import HttpResponse
from django.shortcuts import render
from .models import UserModel

# Create your views here.

def index(request):
# 返回相应response#
return HttpResponse('Hello Django!')


def get_users(request):
users = UserModel.objects.all()
return render(request, 'users.html', {'users': users})

最后添加路由\user\getusers,即可显示

回顾目前文件结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
MYPROJECT
│ db.sqlite3
│ manage.py


├─myproject
│ │ asgi.py
│ │ settings.py
│ │ urls.py
│ │ wsgi.py
│ └─ __init__.py


└─user
│ admin.py
│ apps.py
│ models.py
│ tests.py
│ url.py
│ views.py
│ __init__.py

├─migrations
│ │ 0001_initial.py
│ └─ __init__.py
│ │

└─templates
users.html




后台管理

django自带了后台管理,接下来说怎么使用

admin.py中将model加入后台管理:

1
admin.site.register(加入的模型)

在终端创建超级用户

1
python manage.py createsuperuser

访问admin后台

1
http://127.0.0.1/admin

ps:后台界面的语言,可以通过修改setting.py中的LANGUAGE_CODE来修改

1
LANGUAGE_CODE = "zh-hans"   # 中文;	en-us 英文

实例

1、user包下的admin.py

1
2
3
4
5
from django.contrib import admin
from .models import UserModel
# Register your models here.

admin.site.register(UserModel)

2、注册账号为admin,密码为123456,邮箱直接回测不输入即可

1
2
3
4
5
6
7
8
9
10
11
\myproject> python manage.py createsuperuser
Username (leave blank to use 'ggw_2021'): admin
Email address:
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

创建完后可以看到数据(密码自动加密)

3、访问admin后台,输入账号密码即可

但是我们查看表的时候显示不直观:

可以在model中添加函数__str__(self)

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

# 模型Model -- 表结构
# 类属性 -- 表字段
# 对象 -- 表的一行记录

class UserModel(models.Model):
name = models.CharField(max_length=30, unique=True) # 对应sql:name varchar(30)
age = models.IntegerField(default=18) # 对应sql:age int(30) default
sex = models.CharField(max_length=20) # 对应sql:sex varchar(20)
is_deleted = models.BooleanField(default=False)

def __str__(self):
return f'{self.name} - {self.age}'
# 表结构一旦改变就需要重新数据迁移

修改后显示:





Django路由详解

路由

  • 路由

在实际开发过程中,一个Django 项目会包含很多的 app,这时候如果我们只在主路由里进行配置就会显得杂乱无章,所以通常会在每个 app 里,创建各自的 urls.py 路由模块,然后从根路由出发,将 app 所属的 url 请求,全部转发到相应的 urls.py 模块中。而这个从主路由转发到各个应用路由的过程叫做路由的分发



  • 子路由

主项目 urls.py

引入:from django.urls import include, path

1
path("user/", include('user.url')),


  • 命名空间
1
path('user/',include(('app名字.urls','app名字'),namespace='app名字')),

命名空间用于避免不同应用中相同名称的 URL 冲突。在 urls.py 中定义命名空间,可以使用 app_namenamespace 参数。

示例: 假设 blogshop 应用中都有一个名为 index 的视图函数。为了避免冲突,可以在 urls.py 中设置 app_name

blog 应用 urls.py

1
2
3
4
5
6
7
8
from django.urls import path
from . import views

app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
path('post/<int:id>/', views.post, name='post'),
]

shop 应用 urls.py

1
2
3
4
5
6
7
8
from django.urls import path
from . import views

app_name = 'shop'
urlpatterns = [
path('', views.index, name='index'),
path('product/<int:id>/', views.product, name='product'),
]

主项目 urls.py

1
2
3
4
5
6
from django.urls import include, path

urlpatterns = [
path('blog/', include('blog.urls', namespace='blog')),
path('shop/', include('shop.urls', namespace='shop')),
]

这样,在模板或视图中使用命名空间时,可以区分不同的 URL:

1
2
<a href="{% url 'blog:index' %}">Blog Home</a>
<a href="{% url 'shop:index' %}">Shop Home</a>

通过这样组织路由,可以避免不同应用中的相同名称视图的冲突,并使大型项目的 URL 配置更加清晰。





页面跳转(反向解析、命名空间)

1
2
3
4
5
6
7
8
9
10
{# Url路由 #}
<a href="/user/userlist">url路由的方式:进入用户列表页面</a>a>
<hr>

{# 反向解析 #}
{# userlist 是path路由的name值 #}
<a href="{% url 'userlist' %}">反向解析的方式:进入用户列表页面</a>
<hr>
{# 反向解析: 命名空间 #}
<a href="{% url 'user:userlist' %}">反向解析带命名空间的方式:进入用户列表页面</a>

注意 反向解析的两种方式不要同时出现

反向解析就是通过命名空间来找到路由,然后再通过视图函数解析一次





路由传参

1、在对应app的url.py中:

1
2
# 用户详情
path('userdetail/<int:uid>/', user_detail, name='userdetail')

2、视图函数的参数列表加上参数:

1
2
3
4
# 用户详情
def user_detail(request, uid)
user = UserModel.objects.get(pk=uid) # pk:primary key 主键
return render(request,'user_detail.html',{'user:',user})

3、模版中使用:

1
2
3
<a href="{% url 'user:userdetail' user.id %}">
……
</a>

ps:要保证视图函数参数名和路由参数名一致

ps:参数类型一般就是intstr

ps:多个参数:

1
path('……/<int:a>/<int:b>/', ……, name='……')




重定向

Django路由反向解析是一个非常重要的功能,它可以让我们在代码中使用路由别名替代URL路径,在修改URL时避免代码中的硬编码依赖,同时也可以提高可读性和可维护性。

引入

1
from django.shortcuts import render,redirect,reverse

reverse,就是把命名反转会url,有命名空间需要带命名空间

redirect,跳转到url位置

1
2
3
4
return redirect(reverse('index'))
return redirect(reverse('detail', args=[2]))
return redirect(reverse('detail', kwargs={"id":2}))
return redirect(reverse('user:userdetail'))




Django模版(暂时没做笔记)





Django模型

字段类型

  • 概述

django根据属性的类型确定以下信息

  • 当前选择的数据库支持字段的类型
  • 渲染管理表单时使用的默认html控件
  • 在管理站点最低限度的验证

diango会为表增加自动增长的主键例,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后则django不会再生成默认的主键列



  • 属性命名限制

1、遵循标识符规则

2、由于django的查询方式,不允许使用连续的下划线定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,为了方便使用被导入到django.db.models



  • 使用方法

导入

1
from django.db import models

通过models.Field创建字段类型的对象,赋值给属性



  • 常用字段类型
字段类型 说明
AutoField 一个根据实际ID自动增长的IntegerField,通常不指定,如果不指定,主键字段id将自动添加到模型中
CharField(max_length=字符长度) 字符串,默认的表单样式是 Input
TextField 大文本字段,一般超过4000使用,默认的表单控件是Textarea
IntegerField 整数
DecimalField(max_digits=None, decimal_places=None) 使用python的Decimal实例表示的十进制浮点数
参数说明:
max_digits 位数总数; decimal_places 小数点后的数字位数
FloatField 用Python的float实例来表示的浮点数
BooleanField True/False 字段,此字段的默认表单控制是CheckboxInput
DateField([auto_now=False, auto_now_add=False]) 使用Python的datetime.date实例表示的日期
参数说明:
auto_now: 每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false; auto_now_add: 当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用创建时的日期默认为false
注意: auto_now_add,auto_now,and default 这些设置是相互排斥的他们之间的任何组合将会发 生错误的结果
TimeField 使用Python的datetime.time实例表示的时间,参数同DateField
DateTimeField 使用Python的datetime.datetime实例表示的时间,参数同DateField
FileField 一个上传文件字段
ImageField 继承了FileField的所有属性和方法,但对上传的对进行校验,确保它是个有效的image需要安装Pillow: pip install Pillow

使用讲解



  • 常用字段参数

相当于数据库中的约束

  1. null=True

    • 数据库字段是否可以为空
  2. blank=True

    • Django 的 Admin 中添加数据时是否可以允许空值
    • 一般 null=True & blank=True 搭配着用,出现 null=True 就用 blank=True
  3. primary_key = True

    • 主键,对 AutoField 设置主键后,就会代替原来的自增 id
  4. auto_nowauto_now_add

    • auto_now:自动创建,无论添加或修改,都是当前操作的时间
    • auto_now_add:自动创建,永远是创建时的时间
  5. choices(后台 admin 下拉菜单)

    • USER_TYPE_LIST = [
      • (1, "超级用户"),
      • (2, "普通用户")
      • ]
    • user_type = models.IntegerField(choices=USER_TYPE_LIST, default=1, verbose_name="用户类型")
  6. max_length 最大长度

  7. default 默认值

  8. verbose_name Admin(后台显示的名称)中字段的显示名称

  9. name|db_column 数据库中的字段名称

  10. unique=True 唯一

  11. db_index=True 设置是否建库索引,例如:如果你想通过 name 进行查询的更快的话,给他设置为索引即可以

  12. editable=True 在 Admin 里是否可编辑,不可编辑则不显示

  13. 设置表名

    • class Meta:
      • db_table = 'person'

使用讲解





配置mysql

1
2
3
4
5
6
7
8
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydb',
'USER': 'root',
'PASSWORD':'123456',
'HOST':'127.0.0.1',
'PORT':'3306',
}