环境准备
# 1. 开启一个新的项目 advanceDjango
(venv) E:\PythonLearn\djangoDemo>django-admin startproject advanceDjango # 2. 配置项目同名APP下的settings.py, advanceDjango/advanceDjango/settings.py ALLOWED_HOSTS = ['*'] TEMPLATES = [
'DIRS': [ os.path.join(BASE_DIR, 'templates') # 配置模板目录 ], # 配置数据库, 更换Sqlite3为MySQL DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_advance', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'dbman', 'PASSWORD': 'xxxxxx', 'CHARSET': 'utf8' } } # 3. 安装数据库驱动 pymysql, 默认是mysqlclient (venv) E:\PythonLearn\djangoDemo>pip install pymysql # 创建数据库django_advance mysql> create database django_advance default character set 'utf8'; Query OK, 1 row affected, 1 warning (0.01 sec) # 在 advanceDjango/advanceDjango/__init__.py 引入MySQL 初始化 import pymysql pymysql.install_as_MySQLdb()
一、 请求与响应之Request
1.1 Request对象
1.1.1 Request 请求对象类; 在视图函数的第一个参数上; 请求是由Django框架生成的
1.1.2 请求对象中的普通信息
- path: 请求路径
- method: 请求方法; GET/POST/PUT/DELETE
- content_type: 数据类型, 如请求头的Context-Type: text/html;charset=utf-8
- encoding: 编码方式, 如utf-8
- body: 字节码数据,一般接收上传的json数据
1.1.3 请求对象中的QueryDict属性, QueryDict自动进行url的中文编码处理
- GET: 查询参数, 包含get请求的所有参数
- POST: 表单参数, 包含post/put两个请求方法的参数;PUT上传的数据用body来获取
- COOKIES: 客户端中的当前domain的所有Cookie信息
- FILES: 上传的表单参数中所有的文件对象
- session: 会话中存储的数据(可以跨多个请求)
- META: 客户端的元信息(服务器环境信息、客户端请求信息) REMOTE_ADDR 客户端IP地址
- PATH_INFO REQUEST_METHOD QUERY_STRING CONTENT_TYPE
1.1.4 GET/POST 参数
- 类字典结构; key-value存储数据; key可以重复;
- 获取值: GET.get(),获取不到返回None; GET[key] 获取不到抛出异常;
- 获取所有值: GET.getlist("")
1.2 user应用测试
1.2.1 基础准备, 新增user应用
(venv) E:\PythonLearn\djangoDemo>cd advanceDjango (venv) E:\PythonLearn\djangoDemo\advanceDjango>django-admin startapp user
1.2.2 定义视图函数
def register(request, user_id=None):
return render(request, 'register.html', locals())
1.2.3 定义路由
# 定义总路由, 在settings.py 注册应用
path('user/', include('user.urls', namespace='user')),
# 定义子路由
app_name = 'user'
urlpatterns = [
path('register/', views.register, name='register1'),
path('register/<user_id>/', views.register, name='register2')
]
1.2.4 编写 templates/register.html
<p>
请求路径: {{ request.path }}
<br/>
请求URI: {{ request.get_raw_uri }}
<pre>
URL: 统一资源定位符, 资源的网络地址
URI: 统一资源标识符, 用于Restful规范中
</pre>
</p>
<p>
请求方法: {{ request.method }}
<br>
content_type: {{ request.content_type }}
<br>
encoding: {{ request.encoding }}
<br>
content_params: {{ request.content_params }}
</p>
1.2.5 访问结果

1.2.6 访问 http://127.0.0.1:8000/user/register/11a
[10/Apr/2023 22:41:48] "GET /user/register/11a HTTP/1.1" 301 0 [10/Apr/2023 22:41:48] "GET /user/register/11a/ HTTP/1.1" 200 924
1.3 GET请求参数
<p>
<form method="get" enctype="application/x-www-form-urlencoded">
<input name="name" placeholder="请输入用户名">
<br>
<input name="phone" placeholder="手机号">
<br>
爱好:
{% for love in loves %}
<input type="checkbox"
{% if forloop.first or forloop.last %} # 默认选中第一项和 最后一项
checked
{% endif %}
name="love" value="{{ love }}">{{ love }}
{% endfor %}
<br>
<button>提交</button>
</form>
</p>
<p>
GET请求的查询参数
<ul>
{% for key, value in request.GET.items %}
{% ifnotequal key 'love' %}
<li>{{ key }}:{{ value }}</li>
{% endifnotequal %}
{% endfor %}
<li>
爱好:
{% for item in select_loves %}
{{ item }},
{% endfor %}
</li>
</ul>
</p>
def register(request, user_id=None):
loves = ['H5', 'Python', 'Java', 'GO', 'Linux']
# 获取参数名相同(love)的多个参数值
select_loves = request.GET.getlist('love')
return render(request, 'register2.html', locals())
访问 /user/register , 输入数据后,点击提交

1.4 POST请求参数
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt def register3(request, user_id=None): print(request.POST) print(request.body) return render(request, 'register3.html', locals())
<form method="post" enctype="application/x-www-form-urlencoded">
<input name="name" placeholder="请输入用户名" value="{{ name }}">
<br>
<input name="phone" placeholder="手机号" value="{{ phone }}">
<br>
<button>提交</button>
</form>
<p>
POST请求的查询参数
<ul>
{% for key, value in request.POST.items %}
<li>{{ key }}:{{ value }}</li>
{% endfor %}
</ul>
</p>
POST返回结果
<QueryDict: {'name': ['Tom'], 'phone': ['15566665555']}>
b'name=Tom&phone=15566665555'
POST请求参数格式
# es6-form 格式化: key=value&key=value 格式化的字符串
fetch('', {
method: 'POST',
body: 'name=' + data.name+'&phone='+data.phone,

1.5 PUT请求参数
1.5.1 PUT请求传递json数据
<p>
<button onclick="up_ajax()">ajax发起PUT请求</button>
<script>
function up_ajax() {
data = {
name: 'TangSan',
phone: '15500008753',
loves: ['数学', 'Python', 'Java', '语文', 'Linux']
};
var formdata = document.forms[0]
formdata.append('name', data.name);
formdata.append('phone', data.phone)
fetch('', {
method: 'PUT',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
}).then(response => response.text()).then(html => {
document.write(html)
});
}
</script>
</p>
<p>
请求方法: {{ request.method }} <br>
PUT请求的参数(body): {{ request.body }} <br>
content_type: {{ request.content_type }} <br>
encoding: {{ request.encoding }} <br>
</p>

1.5.2 PUT请求传输form表单数据
body: document.forms[0].serialize,
headers: {
{#'Content-Type': 'application/json;charset=utf-8'#}
'Content-Type': 'application/x-www-form-urlencoded'
}
1.6 上传文件
<form method="post" enctype="multipart/form-data">
<input name="name" placeholder="用户名"><br>
<input name="phone" placeholder="手机号"><br>
<input type="file" name="img"><br>
<button>提交</button><br>
</form>
from django.core.files.uploadedfile import InMemoryUploadedFile
@csrf_exempt
def register4(request, user_id=None):
print(request.method)
print(request.POST)
print(request.FILES)
name = request.POST.get('name')
phone = request.POST.get('phone')
upload_file: InMemoryUploadedFile = request.FILES.get('img')
if upload_file:
print(upload_file.name)
print(upload_file.content_type)
print(upload_file.size)
print(upload_file.charset)
# print(request.body)
if all((
upload_file.content_type.startswith('image/'),
upload_file.size < 120 * 1024
)):
print(request.META.get('REMOTE_ADDR'))
file_name = name + os.path.splitext(upload_file.name)[-1]
# images 目录必须存在, advanceDjango项目目录下
with open('images/' + file_name, 'wb') as f:
for chunk in upload_file.chunks():
f.write(chunk)
f.flush()
return HttpResponse('上传文件成功')
return HttpResponse('请上传小于120KB的图片')
return render(request, 'register4.html', locals())
POST
<QueryDict: {'name': ['Jack'], 'phone': ['15566667777']}>
<MultiValueDict: {'img': [<InMemoryUploadedFile: Django目录结构.png (image/png)>]}>
Django目录结构.png
image/png
54811
None
当保存图片等文件时,目录不存在会报错

二、 请求与响应之Response
2.1 response对象
响应对象是视图函数返回的对象。需自行创建,可由render()/redirect()快速生成response响应对象。
常用的响应类: HttpResponse、 HttpResponseRedirect、 JsonResponse
常用属性与方法:
- content: 响应内容,必须是bytes类型的数据 charset: 编码格式
- status: 响应状态码(200, 3xx, 404, 5xx) content_type: MIME类型
- init(): 初始化内容 write(): 直接写出文本 flush(): 刷新缓冲区
增加响应头:
- 响应对象中存在着 _headers 私有的字典对象 HttpResponseBase类。
- 在Django中, response对象具有dict的特性。 response['Content-Type'] = value
2.2 返回JSON格式数据
def register5(request):
# 返回字符串格式的文本
resp1 = HttpResponse(content='您好'.encode('utf-8'), status=200, content_type='text/html;charset=utf-8')
# 返回图片
with open('images/Jack.png', 'rb') as f:
png_data = f.read()
resp2 = HttpResponse(content=png_data, content_type='image/png')
resp2.setdefault('Content-Length', len(png_data))
# 返回Json格式的数据
json_data = {'name': 'Jackson', 'age': 20}
resp3 = HttpResponse(content=json.dumps(json_data), content_type='application/json')
# 使用JsonResponse返回Json数据
resp4 = JsonResponse(json_data)
return resp4
返回图片

浙公网安备 33010602011771号