【今日习题】
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="../static/plugins/jQuery/jquery.min.js"></script><link href="../static/plugins/bootstrap/bootstrap.min.css" rel="stylesheet"><script src="../static/plugins/bootstrap/bootstrap.min.js"></script><style>.hide {display: none;}</style>
</head>
<body>
<div class="title">一级菜单<p class="item"> 1.1</p><p class="item">1.2</p><p class="item">1.3</p>
</div>
<div class="title">二级菜单<p class="item">2.1</p><p class="item">2.2</p><p class="item">2.3</p>
</div>
<div class="title">三级菜单<p class="item">3.1</p><p class="item">3.2</p><p class="item">3.3</p>
</div><script>$(".title").on("click", function () {$(".item").addClass("hide")$(this).children().removeClass("hide")})
</script>
</body>
</html>
【昨日内容回顾】
'''
请求模型请求首行 : 请求方式 请求路径 HTTP协议版本请求头 : 一堆 k:v 键值对换行 : \r\n请求体参数
响应模型响应首行 : 响应状态码 HTTP协议版本响应头 : 一堆 k:v 键值对换行 : \r\n响应体数据
'''
'''
from wsgiref import simple_serverdef run(request, response):# request 对象中会封存很多请求的参数 # 其中有一个参数叫 PATH_INFO ---> 在请求路径中请求的路径response("200 OK", [])return [b""]def main():# 创建服务端对象server = simple_server.make_server(host="127.0.0.1",port=9696,app=run)# 启动服务端server.serve_forever()
'''
'''
from jinja2 import Templatedata = "" # HTML 源码文件读出来的字符串数据tem_obj = Template(data)
# obj 其实是一个文本数据 所以要对数据进行编码
obj = tem_obj.render({"key":"value"}) # 在前端渲染数据就要用 {{ key }}
obj.encode() # 基于 utf8编码成二进制数据再返回
'''
【一】三板斧对象
"""
# 定义每一个视图函数都必须有一个位置参数 叫 request
def index(request):# render(request, template_name, context=None, content_type=None, status=None, using=None)# request 当前的 request 对象# template_name 当前需要渲染的模板文件的名字 放在 templates 文件夹里面的# context jinja2 语法 给前端传递数据 render({"key":"value"}) === context# content_type : 定义响应文档的类型 text/html / json# status : 响应状态码 默认的状态码就是 200 OK# using : 执行使用的是哪个模板引擎 使用默认的return render(request, "index.html")# settings.py 中的 TEMPLATES 配置块
'''
TEMPLATES = [{# 使用的 Django 提供的模板渲染引擎 我们用过 jinja2 引擎'BACKEND': 'django.template.backends.django.DjangoTemplates',# 检测哪些目录下的 templates 文件夹'DIRS': [],# True 的含义是会自动检测当前自己APP下面的templates文件夹'APP_DIRS': True,# 可选的配置参数'OPTIONS': {'context_processors': [# debug 开发者模式 如果报错了会提示给你详细的报错信息'django.template.context_processors.debug',# request 使用视图函数逇 request 对象'django.template.context_processors.request',# 用户模块'django.contrib.auth.context_processors.auth',# 信息'django.contrib.messages.context_processors.messages',],},},
]
'''
"""
'''
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="../../static/jquery.min.js"></script><link href="../../static/bootstrap.min.css" rel="stylesheet">{# ../(templates)../(user) --> static --> /bootstrap.min.js #}<script src="../../static/bootstrap.min.js"></script></head>
<body>
<h1>这是 index 页面</h1>
</body>
</html>
'''
'''
from user.views import indexurlpatterns = [path('admin/', admin.site.urls),path('index/', index),
]
'''
"""
def func(request):# redirect(to, *args, permanent=False, **kwargs)# to 代表想要重定向的目标地址# 如果写详细的地址 https:www.baidu.com 会重定向到指定的地址上# 如果简写 /index/ 会自动拼接 http://127.0.0.1:8000 + /index/ ---> http://127.0.0.1:8000/index/ 回到了主页上# 如果写 index/ 会自动拼接 当前路径 + index/ ---> http://127.0.0.1:8000/func + /index/ -- > http://127.0.0.1:8000/func/index/# 后面将 分组 要给某个 路径携带参数 args kwargs 传递关键字参数return redirect("index/")'''
# 临时重定向和永久重定向# ● 临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
# ○ A页面临时重定向到B页面,那搜索引擎收录的就是A页面。 # 可以通过 回退回去
# ○ A页面永久重定向到B页面,那搜索引擎收录的就是B页面。 # 不可以通过 回退回去
'''
"""
【二】静态文件static
'''
static
├── css
├── img
├── js
├── plugins
│ ├── bootstrap
│ │ ├── bootstrap.min.css
│ │ └── bootstrap.min.js
│ └── jQuery
│ └── jquery.min.js
└── video
'''
'''
# Static files (CSS, JavaScript, Images)
# 提供了 Static 官方文档链接
# https://docs.djangoproject.com/en/3.2/howto/static-files/# 配置的 Static 静态文件的路由
# 访问静态文件路由 : http://127.0.0.1:8000/static/ + 文件名
# http://127.0.0.1:8000/static/img/1.jpg
# http://127.0.0.1:8000/static/plugins/bootstrap/bootstrap.min.css
STATIC_URL = '/static/'# 在配置一个参数
# 静态文件目录
STATICFILES_DIRS = [# 根目录下的文件目录"static",
]
# 将app目录放在 static 目录下 也会通过静态语法找到制定的文件
# 容易造成信息的泄露
# http://127.0.0.1:8000/static/user/templates/index.html# static 文件夹一般存一些静态的不重要的数据
'''
'''
{# 第一句 : 加载静态文件语法系统 #}
{% load static %}<head><meta charset="UTF-8"><title>Title</title><script src="../../static/plugins/jQuery/jquery.min.js"></script><link href="../../static/plugins/bootstrap/bootstrap.min.css" rel="stylesheet">{# ../(templates)../(user) --> static --> /bootstrap.min.js #}<script src="{% static 'plugins/bootstrap/bootstrap.min.js' %}"></script>{# 页面上的展示是 : <script src="/static/plugins/bootstrap/bootstrap.min.js"></script> #}{# /static/plugins/bootstrap/bootstrap.min.js ---> 从根目录下开始加载 ---> http://127.0.0.1:8000/static/plugins/bootstrap/bootstrap.min.js #}
</head>
'''
【三】request对象初识
"""
def login(request):# 【0】如何查看当前对象有那些属性?# print(dir(request))'''['COOKIES', 'FILES', 'GET', 'META', 'POST', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_current_scheme_host', '_encoding', '_get_full_path', '_get_post', '_get_raw_host', '_get_scheme', '_initialize_handlers', '_load_post_and_files', '_mark_post_parse_error', '_messages', '_read_started', '_set_content_type_params', '_set_post', '_stream', '_upload_handlers', 'accepted_types', 'accepts', 'body', 'build_absolute_uri', 'close', 'content_params', 'content_type', 'encoding', 'environ', 'get_full_path', 'get_full_path_info', 'get_host', 'get_port', 'get_raw_uri', 'get_signed_cookie', 'headers', 'is_ajax', 'is_secure', 'method', 'parse_file_upload', 'path', 'path_info', 'read', 'readline', 'readlines', 'resolver_match', 'scheme', 'session', 'upload_handlers', 'user']'''# META -- 后面讲# COOKIES -- 后面讲# FILES -- 后面讲# body -- 后面讲# headers -- 后面讲# is_ajax -- 后面讲# path -- 后面讲# path_info -- 后面讲# 【1】获取当前请求的方法# methodprint(request.method) # 获取到当前提交的请求的请求方法# GET / POSTif request.method == "GET":# 【2】获取GET请求携带的请求参数# 应该将路径中携带的参数提取出来和数据库或者其他数据进行校验# http://127.0.0.1:8000/login/?username=dream&password=666print(request.GET) # 并且将请求携带的参数转换为字典# <QueryDict: {'username': ['dream'], 'password': ['dasdadsa'], 'hobby': ['music', 'run', 'dance']}>username = request.GET.get("username")password = request.GET.get("password")# 对于一个键多个值的情况要使用 getlist# hobby = request.GET.get("hobby") # dancehobby = request.GET.getlist("hobby") # ['music', 'run', 'dance']print(username, password) # dream 666print(hobby) # ['music', 'run', 'dance']else:# POST# 【3】获取 POST 请求携带的请求体参数# 在POST请求中 携带的数据不会展示在 路径上# http://127.0.0.1:8000/login/print(request.POST) # 并且将请求携带的参数转换为字典# <QueryDict: {'username': ['dream'], 'password': ['66'], 'hobby': ['music', 'run']}>username = request.POST.get("username")password = request.POST.get("password")# 对于一个键多个值的情况要使用 getlisthobby = request.POST.get("hobby") # dance# hobby = request.POST.getlist("hobby") #['music', 'run']print(username, password) # dream 66print(hobby) # ['music', 'run']return render(request, "login.html")
"""
【四】Django连接MySQL
'''
# Django使用的默认的数据库 sqlite3
DATABASES = {'default': {# 使用的哪种数据库引擎 django.db.backends.sqlite3'ENGINE': 'django.db.backends.sqlite3',# BASE_DIR / 'db.sqlite3' : 数据库文件'NAME': BASE_DIR / 'db.sqlite3',}
}# Django链接MySQL数据库'''
'''
import pymysqlpymysql.install_as_MySQLdb()
'''
【五】ORM初识
'''
from django.db import models# Create your models here.# ○ 数据库中的表映射为Python中的类
# 定义一个类 必须继承 models.Model
class Student(models.Model):# 在SQL语句中会创建一个主键 ID# 在Django里面会 给我们默认配一个字段 叫 ID === 我们自己定义的主键ID# DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'# ○ 数据库中的字段映射为Python中的属性# name : 字符串类型# name varchar(32) # 在SQL语句定义的时候要指定默认长度# 在Django定义模型表的时候也要指定默认长度name = models.CharField(max_length=32)# age : 数字类型# age int() # SQL 语句age = models.IntegerField()
'''
'''
python manage.py makemigrations
# make + migrations
'''
'''
将 Python 定义的数据库结构进行转换
'''
'''
python manage.py migrate
# migrations --> migrate
''''''
Operations to perform:Apply all migrations: admin, auth, contenttypes, sessions, user
Running migrations:Applying contenttypes.0001_initial... OKApplying auth.0001_initial... OKApplying admin.0001_initial... OKApplying admin.0002_logentry_remove_auto_add... OKApplying admin.0003_logentry_add_action_flag_choices... OKApplying contenttypes.0002_remove_content_type_name... OKApplying auth.0002_alter_permission_name_max_length... OKApplying auth.0003_alter_user_email_max_length... OKApplying auth.0004_alter_user_username_opts... OKApplying auth.0005_alter_user_last_login_null... OKApplying auth.0006_require_contenttypes_0002... OKApplying auth.0007_alter_validators_add_error_messages... OKApplying auth.0008_alter_user_username_max_length... OKApplying auth.0009_alter_user_last_name_max_length... OKApplying auth.0010_alter_group_name_max_length... OKApplying auth.0011_update_proxy_permissions... OKApplying auth.0012_alter_user_first_name_max_length... OKApplying sessions.0001_initial... OKApplying user.0001_initial... OK
'''
'''
Tools -> run manage.py task ---> makemigrations ---> migrate
'''