django学习(二)
django学习(二)
昨日内容回顾
简易版本框架
import socket # 导入socket模块
server = socket.socket() # 创建服务器对象
server.bind(('127.0.0.1', 8002)) # 放入本机地址和端口号
server.listen(5) # 半链接池
while True:
sock, addr = server.accept() # 等待接收消息和端口号
data = sock.recv(1024) # 不考虑黏包问题直接按照1024字节
data_str = data.decode('utf8') # 按照utf8解码
sock.send(b'HTTP1.1 200 OK\r\n\r\n') # 写入http协议
current_path = data_str.split(' ')[1] # 检索信息获取后缀
if current_path == '/login': # 对后缀做判断,响应不同结果
sock.send(b'hello login!!!')
elif current_path == '/register':
sock.send(b'hello register')
else:
sock.send(b'404 error')
wsgiref模块
from wsgiref import simple_server # 引入wsgiref模块
from urls import urls # 导入路由层
from views import error # 导入视图层
def run(request, response):
"""
:param request: 请求相关的数据
:param response: 响应相关的数据
:return: 返回给客户端的展示数据
"""
print(request) # 字典类型的数据(模块自动处理HTTP请求数据 便于后续数据获取)
response('200 OK', []) # 固定编写 无需掌握
current_path = request.get("PATH_INFO") # 获取地址后缀名
func_name = None # 变量名赋值None
for url_tuple in urls: # ('/register', register) 用变量名接受urls(后缀匹配字典)循环赋值
if current_path == url_tuple[0]: # 比对后缀与后缀字典
func_name = url_tuple[1] # 将后缀字典中对应的v键赋值给变量名
break # 直接返回出去
# for循环运行完毕之后 func_name也有可能是None
if func_name: # 如果变量名不为空
res = func_name(request) # 运行函数,顺手将request也传给函数
else:
res = error(request)
return [res.encode('utf8')] # 将res按照utf8编码并返回出去
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8080, run)
'''一致监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
server.serve_forever()
django
基本操作:
启动django项目的时候,一定要确保同一时间同一个端口号只允许允许一个django项目
# 1.命令操作
django-admin start project mysite
python3 manage.py runserver ip:port
python3 manage.py startapp app01
# 2.pycharm操作
选择django环境即可
两者最需要的区别在于templates文件夹
命令操作不会自动创建并且配置文件中也不会自动添加路径
今日内容详细
django小白必会三板斧
话不多说,先拿到三板斧(重点,需要背下来)
from django.shortcuts import HttpResponse, render, redirect
HttpResponse:HttpRequest类是一个封闭HTTP提交信息的类型,而封闭HTTP输出信息的类型就是HttpResponse类,使用HttpResponse类可以实现三种类型的输出,即文本,URL,二进制流.
def index(request):
# 业务逻辑代码
return HttpResponse("文本")
render:render可以传入三个参数:一是request参数,二是待渲染的html模板文件,三是保存具体数据的字典参数。
def http(request):
# 业务逻辑代码
return render(request, 'html')
redirect:redirect用于重定向,接受一个URL参数,表示让浏览器跳转去指定的URL
def index(request):
# 业务逻辑代码
return redirect("地址")
登录功能
我们可以通过不同的后缀(路由)访问到不同的资源,是因为我们在后端中提前开设了相应的访问接口才可以访问到不同的资源。也就是如果没有接口,那么就不能访问到对应的资源。
1.创建django框架文件
2.去urls.py和views.py编写登录的路由对应关系
3.登录页面的css和js需要自己编写
4.登录页面需要编写form表单获取用户输入,并设置好action提交地址和method提交方式
5.开设静态资源的访问接口
settings.py
# 静态文件资源访问接口固定配置,这一步是将static地址添加到环境中
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
# html页面路径,将bootstrap中css导入到html中
6.配置文件
STATIC_URL = '/static/'
# 类似于钥匙,满足该前缀才可以具备访问静态文件的权限
# 具备权限后,就可以拿到接口前缀文件路径去列表中每个文件夹中查找,找到一个就结束
STATICFILES_DIRS = ['将需要的地址可以添加进环境中'] # 因为是列表,可以存放多个
7.接口前缀动态绑定
如果templates中有很多html文件并且都需要引入静态资源
现在把接口前缀修改了 那么会造成什么结果???>>>:页面无法加载资源
{% load static %}
静态资源
# 编写完成后不会经常被修改的与html页面相关的文件
css文件、js文件、图片文件、第三方框架文件(bootstrap)
上述文件都可以称之为是'静态文件'
在django中静态文件单独开设一个文件夹存储 默认叫static文件夹
在该文件夹内还可以根据功能的不同继续划分不同的文件
css文件夹 js文件 img文件夹 others文件夹
使用后缀访问到静态页面的展示:
访问静态地址中的地址详解:
添加动态前缀绑定展示:
request对象方法
1.get请求和post请求都会触发同一个视图函数login的运行
如何针对不同的请求执行不同的代码
get请求返回一个登录页面
post请求获取用户数据并校验
如果post报错,在settings.py文件中,找到 # 'django.middleware.csrf.CsrfViewMiddleware'注释
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',
]
pycharm链接MySQL
django链接MySQL
settings.py的默认配置
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
修改成我们mysql的配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '库',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '密码',
}
}
3.指定模块
在项目同名的文件夹内的__init__.py
或者应用名的文件夹内的__init__.py
添加一行固定的代码
import pymysql
pymysql.install_as_MySQLdb()
django orm简介
ORM:ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。简单理解为一种框架的格式
映射关系比对
表 类
一行行数据 类产生的一个个对象
数据字段 对象的一个个属性
orm基本使用
# 如果需要使用ORM 需要去应用下的models.py中编写代码
1.编写类代码
class Users(models.Model):
uid = models.AutoField(primary_key=True) # 等价于uid int primary key auto_increment
name = models.CharField(max_length=32) # 等价于name varchar(32)
pwd = models.IntegerField() # 等价于pwd int
2.执行数据库迁移命令
python3 manage.py makemigrations # 记录操作
python3 manage.py migrate # 将操作迁移到数据库
"""
首次执行迁移命令 django还会自动创建一些默认需要使用到的表
"""
3.表名的特征
Users app01_users
由于django支持多个应用 为了区分不同应用下可能会出现相同的表名
所以自动加上了应用的前缀 因为同一个应用下不可能出现相同的表名(只要你是个正常的程序员都不会犯这样的错误)
4.扩展
1.表的主键可以不写 orm会自动帮你写一个名为id的主键
2.每次修改了跟数据库相关的python代码 都需要重新执行迁移命令
针对两个迁移命令 可以采用pycharm提示功能编写
tools
run manage.py task
数据操作
```python
# 1.增
user_obj = models.Users.objects.create(name='jack', pwd='333')
print(user_obj)
print(user_obj.uid)
print(user_obj.name)
print(user_obj.pwd)
# 2.查
res = models.Users.objects.filter(name='jason')
print(res) # ]>
print(res[0]) # Users object
print(res[0].uid) # 1
print(res[0].name) # jason
print(res[0].pwd) # 123
# 3.改
models.Users.objects.filter(uid=1).update(name='jasonNB')
# 4.删
models.Users.objects.filter(uid=3).delete()
```
###
作业
views.py代码
from django.shortcuts import HttpResponse, render, redirect
from django.views.decorators.csrf import csrf_exempt
from django1 import models
# Create your views here.
def yes(request):
return render(request, 'yes.html')
def login(request):
if request.method == 'POST':
if request.POST.get('but') == '登录':
name = request.POST.get('username')
pwd = request.POST.getlist('password')
res = models.User_data.objects.filter(name=name)
if res:
if res[0].name == name and res[0].pwd == int(pwd[0]):
return render(request, 'yes.html')
else:
return HttpResponse('密码错误')
else:
return HttpResponse('账户不存在')
else:
name = request.POST.get('username')
pwd = request.POST.getlist('password')
res = models.User_data.objects.filter(name=name)
if res:
return HttpResponse('账户已存在!!!')
else:
models.User_data.objects.create(name=name, pwd=int(pwd[0]))
return HttpResponse('注册成功')
if request.method == 'GET':
return render(request, 'login1.html')