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 指定

开启静态文件的访问路由后,效果呈现

 

二、request对象请求方法

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()方法

三、Django连接MySQL

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.py0002_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 使用连接池

1、DBUtils · PyPI

python常用库之DBUtils(连接池方式连接数据库)_dbutils python_西京刀客的博客-CSDN博客

 

posted @ 2023-07-27 14:45  凡人半睁眼  阅读(218)  评论(0编辑  收藏  举报