Django 连接数据库、迁移数据库、连接池
一、配置文件介绍
补充:django源码里面的默认配置
from django.conf import settings
1、settings
# 注册应用的 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', ] ################中间件################################################# 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', ] ################中间件################################################# ############day54_dj是项目名 ROOT_URLCONF = 'day54_dj.urls' # 根路由的文件名 #######Django连接数据库的 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } ####修改为中文、时区为上海 LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'
2、form表单的action
用户可以通过表单提交数据到服务器端进行处理,
action
属性是<form>
元素的一个属性,它指定了数据提交的目标地址,即数据将被发送到哪个服务器端处理程序。
action参数的三种情况:
1. 不写或留空,就是朝当前地址提交数据
当 action
属性留空或者不写时,表单数据会默认提交到当前页面的 URL,也就是所谓的“相对路径提交”。
127.0.0.1:8000:'当前文件名前缀',如:127.0.0.1:8000/user_edit
2. 要么全写,完整的绝对 URL:http://127.0.0.1:8000/login/?username=&password= (包括参数)
3. 只写后缀,如<form action="login">,会自动拼接
http://127.0.0.1:8000/login/
3、静态文件的配置(js、jq、bootstrap、html等)
静态模板文件都是放在templates文件夹中,如果没有这个文件夹就自己创建
一般把静态文件放在static文件夹中, 需要手动创建出来这个文件夹
静态文件,针对不同的功能对static文件夹里面的文件进行拆分:
网站使用的CSS文件
网站使用的js文件
网站使用图片
网站使用的第三方库文件
jQuery、bootstrap等
3、静态网页访问不到bootstrap特效分析
浏览器检查发现js、css相关的文件404,原因是django没有开启访问的接口(路由)
form表单action=""参数
全写:http://127.0.0.1:8000/login/?username=&password=
django如何开启静态文件的路由?
在settings中
# 访问静态文件的令牌,以后你只要访问静态文件的路径,就要以/static/开头 STATIC_URL = '/static/' # 静态文件 # 添加静态文件的路径 STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ]
注:
STATIC_URL = '/static/' 是template中html文件指定css、js等效果的前缀,这里写/static/,那么在html文件中引入也要以/static/开头
动态写法:使用{% %} 模版,不管settings中的STATIC_URL 的 '/static/' 怎么改变,这里都会动态加载
{% load static %} <link href=" {% static 'bootstrap_css/bootstrap.min.css' %} " rel="stylesheet"> <script src="{% static 'jq/jquery.js' %}"></script> <script src="{% static 'bootstrap_js/bootstrap.min.js' %}"></script>
项目中的静态文件存放路径在settings中STATICFILES_DIRS 指定
开启静态文件的访问路由后,效果呈现
二、
1、查看请求方法和携带的参数
2、视图函数中request的解释
在 Django 中,当客户端发起请求时,Django 会将请求信息封装在一个 HttpRequest
对象中,并将该对象传递给相应的视图函数。
这个 HttpRequest
对象就是 request
参数,它包含了客户端请求的所有信息,如请求头、请求方法、GET 和 POST 参数、用户信息等。
当在 app01
应用中定义了一个视图函数 login
,Django 会在客户端请求与该视图函数的 URL 相匹配时,自动调用该视图函数,并将 HttpRequest
对象作为第一个参数传递给它。所以,视图函数的定义类似于下面这样:
# app01/views.py from django.http import HttpResponse def login(request): # 在这里处理客户端的请求,访问 request 对象获取请求信息 # 例如:获取 GET 参数、POST 参数、用户信息等 # 然后进行相应的处理逻辑 # 返回一个 HttpResponse 对象作为响应 return HttpResponse("Hello, this is the login page.")
request
参数在视图函数中非常重要,它是处理客户端请求的入口,你可以从该对象中获取请求所需的所有信息,并根据业务逻辑进行处理,最后返回一个HttpResponse
对象作为响应,将结果返回给客户端。
3、request.method用法
print(request.POST) # <QueryDict: {'username': ['jason'], 'password': ['123']}> print(request.POST.get('username')) # ['jason'] # jason print(request.GET) # <QueryDict: {'username': ['jason'], 'password': ['123']}> print(request.GET.get('username')) # ['jason'] # jason
注:
1. form表单中指定提交服务器的地址和请求方法
<form action="login" method="POST">
2. request.POST拿到的数据是字典
# <QueryDict: {'username': ['zjz'], 'password': ['123']}> print(request.POST.get('username')) print(request.POST.get('password'))
此处的POST.get方法只取最后一个值,v是列表,里面有一个值,所以直接拿到值。如果有多个值,只取最后一个
需要取多个值的时候使用request.POST.getlist()方法
三、
1、安装pymysql并配置
在项目的任意的__init__.py中或者 settings 加入下面两行代码
这两行代码的意思就是把底层的mysqldb模块换成pymysql
import pymysql pymysql.install_as_MySQLdb() # 猴子补丁
补充:
"猴子补丁"是一种编程术语,指的是在运行时动态修改类或模块,以改变或定制其行为。这种技术通常用于在不修改源码的情况下,覆盖或修改现有的代码行为。
对于pymysql.install_as_MySQLdb()
来说,这段代码的主要作用就是将PyMySQL注册为MySQLdb。也就是说,当其他代码尝试导入MySQLdb时,Python会将这个导入重定向到PyMySQL,这样,代码就可以无缝切换到PyMySQL,而不需要修改任何已经导入MySQLdb的代码。
举个例子,如果你的代码中使用了MySQLdb:
import pymysql pymysql.install_as_MySQLdb() import MySQLdb
即使你的代码仍然在尝试导入MySQLdb,实际上导入的是pymysql。这就是猴子补丁的工作方式。
需要注意的是,猴子补丁虽然非常方便,但也要小心使用,因为它修改了运行时的行为,可能会引发一些难以诊断的问题。
2、settings中 设置数据连接信息
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_user', # 库名 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', 'PASSWORD': 'password', 'CHARSET': 'utf8mb4' } }
补充:mac M1 安装mysqlclient
brew install pkg-config mysql pip3 install mysqlclient
三、Django中的ORM
1、ORM:对象映射模型
# 以后在django中写根数据库相关的代码时候,就不用再写原生的SQL语句了,直接通过python代码来操作数据的增删改查.
orm的书写位置:在models.py中书写
表 >>>>> 类名
记录 >>>>> 对象
字段 >>>>> 属性
class User(models.Model): username = models.CharField(max_length=64) password = models.CharField(max_length=64)
注意:
所有的类必须继承models.Model
其中id字段会自动生成,且是主键自增,不需要重复写代码
id int primary key auto_increment (id = models.AutoField(primary_key=True)
2、类写完之后,一定要做数据库迁移,真正的在数据库中生成表
********************************************************************************
python36 manage.py makemigrations # 它的作用是把数据库的迁移记录保存下来
python36 manage.py migrate # 真正的把数据表创建出来
********************************************************************************
makemigrations 生成的数据库迁移文件(migration files)通常以数字开头,表示它们的执行顺序,以及一个简要的描述,
例如:0001_initial.py
、0002_auto_20230715_1234.py
等。这些迁移文件是由 makemigrations
命令根据你的模型定义生成的,它们包含了关于如何在数据库中创建或修改表结构的信息。
或者在pycharm中设置:
manage.py@djangoProject > makemigrations bash -cl "/usr/local/bin/python3.6 ... Migrations for 'app01': app01/migrations/0001_initial.py - Create model User Following files were affected /Users/sanpangdan/Desktop/djangoProject/app01/migrations/0001_initial.py manage.py@djangoProject > migrate bash -cl "/usr/local/bin/python3.6 .... Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying sessions.0001_initial... OK
3、链式表达式的思想
res=models.Author.objects.filter(name=username, password=password).all()
res是对象,多次点出方法是因为前一个函数方法 ruturn self ,返回值为函数本身,所以可以连续点方法
四、ORM中的增删改查
前提: models文件中Userinfo继承了Django提供的models.Model
类,因此具有ORM的能力
class Userinfo(models.Model): username = models.CharField(max_length=64) password = models.CharField(max_length=64) age = models.IntegerField() gender = models.CharField(max_length=64) # 当打印对象时自动触发,返回用户名 def __str__(self): return self.username
在views视图层代码中,导入 from app01 import models
1、增加记录
models.Userinfo.objects.create(username='zjz', password='123', age=18, gender='male') models.Userinfo.objects.create(username='ldj', password='123', age=19, gender='male') models.Userinfo.objects.create(username='ccy', password='123', age=20, gender='male')
增加字段(在models文件中增加字段后,重新迁移数据文件)
class Userinfo(models.Model): username = models.CharField(max_length=64) password = models.CharField(max_length=64) age = models.IntegerField() gender = models.CharField(max_length=64) ls_delete = models.BooleanField(default=False)
ls_delete
字段表示的是一个布尔值(例如,表示用户是否被删除),使用 models.BooleanField
,默认为False(0)
2、删记录
硬删除
models.Userinfo.objects.filter(username='zjz', age='18').delete()
软删除
数据库中设计一个ls_delete 字段,0代表存在,设置为默认值,1 表示删除
3、改
res=models.表名(类名).objects.update(username='', password='') # 全表更新 res=models.表名(类名).objects.filter().update(username='', password='') '''返回的结果才是影响的行数''' # 第二种方式: # 先查询 user_obj = models.表名(类名).objects.first() user_obj.username = username user_obj.save()
4、查记录
res = models.Userinfo.objects.all() print(res) res1 = models.Userinfo.objects.filter(username='zjz', age='18').first() print(res1)
五、简单的登录验证
1、导入app01的models 模块使用User的 objects:小组件,里面封装了很多方法
from app01 import models
而app01中的model模块
from django.db import models class User(models.Model): username = models.CharField(max_length=64) password = models.CharField(max_length=64)
models.User.objects.filter 查询数据库的记录
res = models.User.objects.filter(username=username, password=password).all() # and 查询 # res = models.User.objects.filter(username=username, password=password).first() # and 查询
2、在视图函数里面利用 request 做判断请求方法,做出不同的回应
if request.method == "POST": 。。。。
3、完整代码
两个视图函数,一个登录,一个注册
from django.shortcuts import render, HttpResponse, redirect from app01 import models def login(request): # 在这里需要判断出是哪种请求方式? # 如果是GET请求只做渲染页面,POST请求就需要做登录逻辑处理 # print(request.POST) # <QueryDict: {'username': ['zjz'], 'password': ['123']}> # print(request.POST.get('username')) # print(request.POST.get('password')) # 此处的get只取最后一个值,列表里面自由一个值,所以直接拿到值 # 需要取多个值的时候使用request.POST.getlist()方法 # 判断POST请求 if request.method == "POST": # 接收用户名和密码 username = request.POST.get("username") password = request.POST.get("password") # 判断usernamer和password等于数据库的内容 # 如何查询数据库的数据 # select * from user where username =jack and password = 123 # objects:小组件,里面封装了很多方法 res = models.User.objects.filter(username=username, password=password).all() # and 查询 # res = models.User.objects.filter(username=username, password=password).first() # and 查询 # print(res) # <QuerySet [<User: User object>]> # QuerySet可以点出来很多方法 ''' Django框架中的QuerySet对象,而不是普通的Python列表。在Django中,QuerySet是一个特殊的对象,用于执行数据库查询并返回结果集。 它类似于数据库中的查询结果,但并不是普通的Python列表。这个QuerySet包含一个或多个对象,这些对象是从数据库中获取的数据记录.all() 方法。 ''' # if username == res[0].username and password == res[0].password: if res: return HttpResponse('登录成功!') else: return HttpResponse('登录失败!') return render(request, 'login.html') def register(request): # 判断POST请求 if request.method == "POST": # 接收用户名和密码 username = request.POST.get("username") password1 = request.POST.get("password1") password2 = request.POST.get("password2") if password1 == password2: res = models.User.objects.create(username=username, password=password1) # print(res) #User object if res: return HttpResponse('注册成功!') else: return HttpResponse('二次密码不匹配!') return render(request, 'register.html')
备注:
res 是一个User object,可以使用对象点属性,来进行操作
比如: 这里点的时候没有提示
res.username, res.password, res.id六、重新迁移数据库文件
已经迁移过表了---> 已经存在auth的user表了,如果再去继承AbstractUser,再写用户表,就会出错
需要settings中注册: AUTH_USER_MODEL = 'app01.AuthUser'
1、先删除数据库
2、 删迁app移文件(不要删__init__.py和migrations文件夹)
3、删除django内置app的admin和auth的迁移文件
4、添加部分字段,让填写默认值,参数设置null=True
七、django 使用连接池
python常用库之DBUtils(连接池方式连接数据库)_dbutils python_西京刀客的博客-CSDN博客