49. django之视图层函数_静态文件_request对象_ORM

1. 视图层三个常用函数

1.1 HttpResponse

HttpResponse用于返回字符串类型的数据。例如,当需要直接向浏览器返回一段文本信息时,就可以使用它。

代码示例:

(1)在user应用的views.py中导入该模块,定义login函数

(2)urls.py中导入login,添加对应关系

(3)运行django项目

1.2 render

render函数用于返回HTML文件,并且支持模板语法,可以实现动态页面的渲染。它允许我们将数据传递给HTML模板,并在模板中使用这些数据来生成最终的HTML页面。

代码示例:

(1)user应用下新建templates文件夹,新建index.html文件

(2)user的view.py中定义index函数

(3)urls.py中导入函数,添加对应关系

(4)运行项目

(5)补充知识点

[5.1]定义视图函数

def index(request):
    # 返回页面对象
    return render(request, 'index.html')

定义每一个视图函数都必须有一个位置参数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:执行使用的是哪个模板引擎 使用默认的

[5.2]定义模板文件

可以在项目根目录下手动创建一个static文件夹用来存储(CSS、JavaScript、图片等)静态文件

模板文件路径为: user/templates/index.html

<!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">
    <script src="../../static/bootstrap.min.js"></script>

</head>
<body>
<h1>这是 index 页面</h1>
</body>
</html>

当在模板文件中引入静态文件时,上方代码中一个点表示该模板文件,每增加一个点向上增加一级,四个点即项目根目录

1.3 redirect

redirect用于实现重定向,可以将用户从一个页面跳转到另一个页面。括号内可以填写其他网站的完整URL,也可以是自己网站的某个路由后缀。

代码示例:

(1)定义函数

(2)添加对应关系

(3)运行项目

浏览器输入register自动重定向到login

(4)补充知识点

[4.1]参数之目标地址

redirect(to, *args, permanent=False, **kwargs)

to:想要重定向的目标地址

  如果写详细的地址:https://www.ox.ac.uk,会重定向到该地址上

def register(request):
    print('欢迎来到注册函数')
    # 重定向路由
    return redirect('https://www.ox.ac.uk/')

  如果简写成/index/会将127.0.0.1:8080/register重定向到127.0.0.1:8080/index上

def register(request):
    print('欢迎来到注册函数')
    # 重定向路由
    return redirect('/index/')

  如果写成index/会使用127.0.0.1:8080/register对index进行拼接

def register(request):
    print('欢迎来到注册函数')
    # 重定向路由
    return redirect('index/')

[4.2]临时重定向、永久重定向

临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。 # 可以通过 回退回去
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。 # 不可以通过 回退回去

2. 静态文件

2.1 概念

在Django项目中,没有默认的名称为static的文件夹。
通常,静态文件(如CSS、JavaScript、图片img、视频video、bootstrap框架等)需要手动创建一个static文件夹来存放,这个文件夹可以放在项目的根目录下。

2.2 静态文件配置

[1] 后端

settings.py中默认有STATIC_URL = '/static/',该配置类似于访问静态文件的令牌

在settings.py中增加一个参数,STATICFILES_DIRS = ["static"],该static目录在根目录下

 

进行后端配置后,即可通过完整路径访问

[2] 前端

前端可以使用语法对路径进行简写

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'plugins/jQuery.js'%}s"></script>
</head>
<body>
    <p>索引页面</p>
</body>
</html>

3. request对象

3.1 引入

static的plugins目录下添加bootstrap、jquery文件

user应用的templates文件夹中创建login.html文件,引入bootstrap、jquery

views.py中定义login函数,返回login.html页面对象

urls.py中添加对应关系

以form表单为例,编写完整的login.html代码

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'plugins/jQuery.js' %}"></script>
    <script src="{% static 'plugins/bootstrap.js' %}"></script>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap.css' %}">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">欢迎来到登陆页面</h1>
            {#      action : 数据提交地址,不写默认提交到当前地址,写了则为指定地址      #}
            {#      method : 请求方式,get、post      #}
            <form action="" method="get">
                <div class="form-group">
                    <label for="inputUsername">Username</label>
                    <input type="text" class="form-control" id="inputUsername" name="username" placeholder="Username">
                </div>
                <div class="form-group">
                    <label for="inputPassword">Password</label>
                    <input type="password" class="form-control" id="inputPassword" name="password"
                           placeholder="Password">
                </div>
                <label class="checkbox-inline">
                    <input type="checkbox" id="inlineCheckbox1" name="hobby" value="music"> music
                </label>
                <label class="checkbox-inline">
                    <input type="checkbox" id="inlineCheckbox2" name="hobby" value="run"> run
                </label>
                <label class="checkbox-inline">
                    <input type="checkbox" id="inlineCheckbox3"  name="hobby" value="dance"> dance
                </label>
                <br>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
        </div>
    </div>
</div>
</body>
</html>
View Code

当以上代码为get请求时,会将请求参数携带在请求路径上

当请求为post时:

在浏览器中临时修改为post

post的请求路径上没有参数

 报了以上错误,解决方法是将settings.py中MIDDLEWARE的csrf相关注释掉

注释之后post请求输入用户名、密码进行submit不会再报错

3.2 request对象属性

[1]查看request有哪些属性

在views.py中打印request的属性

当浏览器中触发login时:

[2] 获取某个请求具体信息

在view.py中打印request的method

 当前端访问login触发login函数时,即打印该方法

[3] 获取get请求的请求体参数

login.html代码:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'plugins/jQuery.js' %}"></script>
    <script src="{% static 'plugins/bootstrap.js' %}"></script>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap.css' %}">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">欢迎来到登陆页面</h1>
            {#      action : 数据提交地址,不写默认提交到当前地址,写了则为指定地址      #}
            {#      method : 请求方式,get、post      #}
            <form action="" method="get">
                <div class="form-group">
                    <label for="inputUsername">Username</label>
                    <input type="text" class="form-control" id="inputUsername" name="username" placeholder="Username">
                </div>
                <div class="form-group">
                    <label for="inputPassword">Password</label>
                    <input type="password" class="form-control" id="inputPassword" name="password"
                           placeholder="Password">
                </div>
                <label class="checkbox-inline">
                    <input type="checkbox" id="inlineCheckbox1" name="hobby" value="music"> music
                </label>
                <label class="checkbox-inline">
                    <input type="checkbox" id="inlineCheckbox2" name="hobby" value="run"> run
                </label>
                <label class="checkbox-inline">
                    <input type="checkbox" id="inlineCheckbox3"  name="hobby" value="dance"> dance
                </label>
                <br>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
        </div>
    </div>
</div>
</body>
</html>

一个键一个值的情况:

当前端提交数据时,即可获取请求体参数

 

 一个键多个值的情况:

对于一个键多个值,get 只会获取列表最后一个元素,getlist 直接将列表取出(多选项)

4. django连接MySQL数据库

4.1 查看默认数据库

在settings.py中,有一个配置项是配置数据库的

django默认使用sqlite3数据库

4.2 指定数据库

[1] 修改为MySQL数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "django_db",    # 数据库名字
        "USER": "root",    # 数据库实际用户名
        "PASSWORD": "123456789",  # 数据库实际密码
        "HOST": "127.0.0.1",     # 数据库 IP
        "PORT": 3306,
        "CHARSET": "utf8mb4",     # 数据库编码
    }
}

修改完成后启动django项目报错

[2] 解决以上报错的方法

(1) 猴子补丁

安装pymsql:pip install pymysql   (如已安装可忽略此步)

在_ _init_ _.py中添加以下代码

import pymysql

pymysql.install_as_MySQLdb()

重启项目后报找不到库的错误

创建该数据库,重启django项目,不再报错

(2)安装第三方模块 

pip install mysqlclient

MacOS无法通过pip安装mysqlclient

Windows安装后重启django项目不再报错

5. ORM介绍

5.1 概念

[1] 什么是ORM

ORM是一种将对象与关系型数据库之间的映射的技术,主要实现了以下三个方面的功能:

数据库中的表映射为Python中的类

数据库中的字段映射为Python中的属性

数据库中的记录映射为Python中的实例

ORM的主要优点是可以减少开发人员编写重复的SQL语句的时间和工作量,并且可以减少由于SQL语句的调整和更改所带来的错误。

[2] Django ORM的优点

与其他ORM框架相比,Django ORM拥有以下优点:
简单易用:Django ORM的API非常简单,易于掌握和使用。
丰富的API:Django ORM提供了丰富的API来完成常见的数据库操作,如增删改查等,同时也支持高级查询和聚合查询等操作。
具有良好的扩展性:Django ORM可以与其他第三方库进行无缝集成,如Django REST framework、Django-Oscar等。
自动映射:Django ORM支持自动映射,开发者只需要定义数据库表的结构,就可以自动生成相应的Python类,从而减少开发过程中的重复代码量。

5.2 ORM表操作

[1] 定义模型表

根据概念,在python中定义类转换为数据库中的表

在应用--models.py文件中定义模型表

from django.db import models


# Create your models here.

class Student(models.Model):  # 定义学生类(学生表),此文件中的类必须继承models.Model
    name = models.CharField(max_length=32)  # 类比于数据库的name varchar(32)
    age = models.IntegerField()  # 类比于数据库的age int()

[2] 数据库迁移

方式一:命令行

(1)生成迁移文件

此步骤将操作记录在migrations文件夹中,虽然文件夹内有相关文件,但是没有同步到数据库中,所以数据库是没有数据的

运行命令需要在有manage.py的路径下

生成0001_initial.py文件

 在setttings.py中会默认配置数据库的id

(2)启动迁移任务

将操作同步到数据库

方式二:task任务

Tools -> run manage.py task ---> makemigrations ---> migrate 

新建的club表被同步到数据库

[3] 表名称

以上从python类同步到数据库后,表名称为:应用名_类名

在python类下配置一个Meta类,则数据库中的表名称以Meta类中定义为准

class Student(models.Model):  # 定义学生类(学生表),此文件中的类必须继承models.Model
    name = models.CharField(max_length=32)  # 类比于数据库的name varchar(32)
    age = models.IntegerField()  # 类比于数据库的age int()

    class Meta:
        db_table = "student"

5.3 ORM字段操作

[1] 增加字段

增加一个grade字段

class Student(models.Model):  # 定义学生类(学生表),此文件中的类必须继承models.Model
    name = models.CharField(max_length=32)  # 类比于数据库的name varchar(32)
    age = models.IntegerField()  # 类比于数据库的age int()
    grade = models.IntegerField()

进行数据库的重新迁移:makemigrations--migrate

出现以下提示:

1) 现在提供一次性默认值(将在所有现有行上设置此列的空值)
2) 退出,让我在models.py中添加一个默认值

 选择2退出,给grade默认空值即可

class Student(models.Model):  # 定义学生类(学生表),此文件中的类必须继承models.Model
    name = models.CharField(max_length=32)  # 类比于数据库的name varchar(32)
    age = models.IntegerField()  # 类比于数据库的age int()
    grade = models.IntegerField(default='')

注意:字符串类型默认值default="",数字类型默认值default=None

class Student(models.Model):  # 定义学生类(学生表),此文件中的类必须继承models.Model
    name = models.CharField(max_length=32)  # 类比于数据库的name varchar(32)
    age = models.IntegerField()  # 类比于数据库的age int()
    a = models.IntegerField(default=None)
    b = models.CharField(max_length=32, default="")
    c = models.IntegerField(default=None)

重新迁移:makemigrations--migrate

[2] 删除字段

models.py中删除所要删除的字段,重新迁移:makemigrations--migrate

例:以上数据表删除c字段

class Student(models.Model):  # 定义学生类(学生表),此文件中的类必须继承models.Model
    name = models.CharField(max_length=32)  # 类比于数据库的name varchar(32)
    age = models.IntegerField()  # 类比于数据库的age int()
    a = models.IntegerField(default=None)
    b = models.CharField(max_length=32, default="")
    # c = models.IntegerField(default=None)

[3] 约束条件

含义 sql语句 ORM
可以为空 null null=True
不可以为空 not null null=False

5.4 创建django临时环境

在django中操作模型表,必须启动django

操作模型表须在视图函数内

为了测试增删改查数据的方便,可以使用以下步骤创建django临时环境

第一步:在django项目中,定义一个scripts目录,用来存放自定义脚本,在该目录中,创建一个py文件用来测试增删改查数据

第二步:打开manage.py文件,复制main函数里第一行代码,项目名称不同则参数不同                        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj2.settings')

第三步:导入django模块

第四步:导入django模型表

第五步:运行django启动命令

第六步:操作模型表

5.5 ORM数据操作

[1] 增加数据

在5.4的基础上使用临时环境进行测试

方式一(常用):

模型表.objects.create(字段名=字段值)

方式二(不常用):

模型表(字段名=字段值)

[2] 查询数据

(1)语法

获取到当前表中的全部数据:模型表名.objects.all()

 

根据指定条件筛选数据:
方式一:模型表名.objects.get(筛选字段名=筛选字段值)
方式二:模型表名.objects.filter(筛选字段名=筛选字段值)

 

去除指定条件的数据:
模型表名.objects.exclude(筛选字段名=筛选字段值)

(2)代码

 

all方法获取所有数据

import os
import django

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj2.settings')
    django.setup()
    from user.models import Student

    result = Student.objects.all()
    print(result)  # 返回值是一个QuerySet对象,列表里存放的就是每一条记录
    student_one = result[0]
    print(student_one, type(student_one))  # Student object (1) <class 'user.models.Student'>
    print(student_one.name)
    print(student_one.age)

 

 get方法当参数存在时就获取,不存在就报错,多于1个就报错

student_one = Student.objects.get(id=1)  # 存在则获取
print(student_one.name)

student_two = Student.objects.get(id=2)  # 不存在则报错

student_three = Student.objects.get(name='avril')  # 多于1个也报错

 

filter方法当参数存在时就获取,不存在不会报错,多于1个也不会报错

import os
import django

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj2.settings')
    django.setup()
    from user.models import Student

    result = Student.objects.filter(id=1)  # 存在则获取
    print(result)
    print(result[0].name)

result = Student.objects.filter(name='avril').first()  # 获取第一条符合的记录
print(result)
print(result.id)

result = Student.objects.filter(name='avril').last()  # 获取最后一条符合的记录
print(result)
print(result.id)

result = Student.objects.filter(id=20)  # 不存在不会报错
print(result)

result = Student.objects.filter(name='avril')  # 多于1个不会报错
print(result)

 

exclude去除掉符合条件的记录

result = Student.objects.exclude(id=14)  # 去除掉id为14的记录
print(result)

[3] 删除数据

方式一:过滤后直接删除

Student.objects.filter(id=14).delete()

如果有多条记录符合括号过滤参数,则会删除所有符合的记录

 

方式二:先过滤出对象,再删除对象

obj = Student.objects.get(id=15)
obj.delete()

[4] 修改数据

方式一:查询并直接修改

模型表.objects.filter(属性名=属性值).update(新的参数)

result = Student.objects.filter(id=4).update(name='ronaldo')
print(result)
result2 = Student.objects.filter(name='avril').update(age=19)
print(result2)

返回值是修改记录的条数

 

方式二:先查询得到对象,再修改对象

    obj = Student.objects.get(id=4)
    obj.name = 'cristiano'
    obj.save()  # save()保存不能忽略

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

posted @ 2025-02-06 22:00  hbutmeng  阅读(45)  评论(0)    收藏  举报