Django入门
- 启动django项目之后 如何添加更多的功能
- 回想自己编写的web框架 如果要添加功能 就去urls.py和views.py
【1】添加URL映射
- 在项目的
urls.py
文件中,通过导入相应的应用(app)及其视图函数,并使用path()
或include()
函数来定义 URL 映射规则。 - 例如,如果要在名为 "myapp" 的应用中添加一个用于显示博客文章列表的 URL,则可以在
urlpatterns
中添加如下配置
from django.urls import path
from . import views
urlpatterns = [
path('blog/', views.blog_list, name='blog_list'),
]
- 这将把 "/blog/" 映射到
views.blog_list
视图函数。
【2】添加视图函数
- 然后,在对应的 "myapp/views.py" 文件中,创建视图函数以处理 HTTP 请求。
- 例如,
blog_list
可能如下实现:
from django.shortcuts import render
from .models import BlogPost
def blog_list(request):
posts = BlogPost.objects.all()
return render(request, 'myapp/blog_list.html', {'posts': posts})
- 这里假设有一个名为 "BlogPost" 的模型,并有一个包含模板
blog_list.html
的对应 HTML 模板文件。
【一】Django小白必会三板斧
【1】HttpResponse
HttpResponse
: 这是 Django 自带的类,用于构建基本的 HTTP 响应。- 例如,当需要返回纯文本或 JSON 数据时,可以这样创建响应:
# 给一个位置参数 request
def index(request):
print(request)
# 返回文本和JSON数据时
return HttpResponse("OK")
【2】render
- 主要用于返回html文件 并且支持模板语法(django自己写的)
render()
: 这个函数用于从给定的模板加载内容,并将其插入到 HTTP 响应中作为 HTML 内容发送给客户端。- 例如,在上面的
blog_list
视图中,我们使用了它来返回带有博客文章列表的 HTML:
from django.http import HttpResponse
from django.shortcuts import render, redirect
# Create your views here.
# 给一个位置参数 request
def index(request):
print(request)
# request: 当前request对象
# template_name: 当前APP下面有一个template文件夹
# render负责返回前端页面
return render(request, "index.html")
【3】redirect
- 主要用于重定向 括号内可以写其他网站的全称 也可以自己网站的后缀
redirect()
: 该函数用于向用户返回一个 HTTP "Redirect" 响应,使浏览器跳转至指定的 URL。
from django.http import HttpResponse
from django.shortcuts import render, redirect
# Create your views here.
# 给一个位置参数 request
def index(request):
print(request)
# request: 当前request对象
# template_name: 当前APP下面有一个template文件夹
# render负责返回前端页面
return redirect('/home/')
def home(request):
print(request)
return render(request, "index.html")
- urls.py
from django.contrib import admin
from django.urls import path
from app01.views import index, home
urlpatterns = [
path('admin/', admin.site.urls),
# 注册路由和视图函数的映射关系
path("index/", index),
path("home/", home, name="home")
]
【补充】django自带重启功能
- 当识别到项目中代码有变化之后 隔段时间会自动重启 但是有时候较慢
【二】静态文件配置说明
【1】模版文件
- 我们将html文件默认都放在templates文件夹下
【2】资源文件
-
我们将网站所使用的静态文件默认都放在static文件夹下
静态文件:前段已经写好,能直接使用的文件 网站写好的JS文件 网站写好的CSS文件 网站用到的图片文件 第三方框架 ... 拿来直接就可以使用的文件
-
一般情况我们再static文件夹下还会对文件进行划分
- js文件夹
- css文件夹
- img文件夹
- plugins文件夹
-
在浏览器中输入url能够看到对应的资源
-
是因为后端提前开设了相关的接口
-
如果访问不到资源,说明后端没有开设相关资源的端口
【3】静态文件配置
- Django静态文件配置官网:https://docs.djangoproject.com/en/3.2/howto/static-files/
【1】配置文件增加配置
(1)后端
settings.py
配置文件中增加如下配置
# 静态文件配置
# 默认查找位置是当前APP的目录下
# 这个配置定义了静态文件应用在启用 FileSystemFinder 查找器时将穿越的额外位置
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
(2)前端
- 在前端页面中增加如下配置,即可使用静态文件模版语法
# 第一步
# 在前端页面中的第一行
# {% load static %}
# 第二步:使用静态文件
# {% static 'avatar/1.jpg' %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>当前是index页面</h1>
<img src="{% static 'avatar/1.jpg' %}" alt="">
</body>
</html>
【2】配置文件说明
- 如果想要访问static静态文件,就必须以static开头
- 如:
/static/plugins/Bootstrap/js/bootstrap.js/bootstrap.min.js
- 如:
【三】request对象方法
【1】提交GET请求
(1)前端
-
form表单中action属性,不写默认是当前路由地址
-
form表单中的method属性,不写默认是GET请求
-
前端页面
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
{# <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>#}
{# <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#}
{# <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#}
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h1 class="text-center">注册页面</h1>
<form action="" method="get"></form>
<form action="" method="post">
{# action : 指定提交数据的路由地址 ,如果不写默认是当前路由地址 #}
<div>username:<input type="text" class="form-control" name="username"></div>
<div>password:<input type="text" class="form-control" name="password"></div>
<div>
hobby :
<input type="checkbox" name="hobby" value="music">音乐
<input type="checkbox" name="hobby" value="sport">运动
<input type="checkbox" name="hobby" value="swim">游泳
</div>
<div><input type="submit" class="btn btn-success" id="btn_submit"></div>
</form>
</div>
</div>
</div>
</body>
</html>
(2)后端
- app01/views.py
def register(request):
print(request)
print(request.method)
return render(request, "register.html")
- urls.py
from django.contrib import admin
from django.urls import path
from app01.views import index, home, register
urlpatterns = [
path('admin/', admin.site.urls),
# 注册路由和视图函数的映射关系
path("index/", index),
path("home/", home, name="home"),
path("register/", register)
]
前端路由地址访问
【2】提交POST请求
- 修改上述前端代码的get就可以了,改成post
- 如果post请求报错修改settings文件里的其中一条进行注释,后续会继续学习解决办法
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',
]
【3】request对象属性和方法
【1】request.method
- 获取发起请求的请求方式
- get请求携带的数据是由大小限制的
- post请求携带的请求参数没有限制
【2】request.post
- 获取用户输入的请求数据,但不包含文件
- 返回的是:大写字符串
【3】get/getlist
get
只会获取列表最后一个元素getlist
直接将列表取出(多选项)
示例:
(1)register.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
{# <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>#}
{# <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#}
{# <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#}
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h1 class="text-center">注册页面</h1>
<form action="" method="get"></form>
<form action="" method="post">
{# action : 指定提交数据的路由地址 ,如果不写默认是当前路由地址 #}
<div>username:<input type="text" class="form-control" name="username"></div>
<div>password:<input type="text" class="form-control" name="password"></div>
<div>
hobby :
<input type="checkbox" name="hobby" value="music">音乐
<input type="checkbox" name="hobby" value="sport">运动
<input type="checkbox" name="hobby" value="swim">游泳
</div>
<div><input type="submit" class="btn btn-success" id="btn_submit"></div>
</form>
</div>
</div>
</div>
</body>
</html>
(2)后端
- app01/views.py
def register(request):
# 【1】第一个方法 request.method : 获取到当前请求的请求方式
print(request.method) # GET / POST
# 如果是 POST 请求 会报错 CSRF verification failed. Request aborted.
# 解决办法:注释掉settings.py文件中的一个配置项 django.middleware.csrf.CsrfViewMiddleware 注释掉
# 【2】第二个方法 : request.GET : 获取到GET请求携带的参数
if request.method == "GET":
data = request.GET
print(data) # <QueryDict: {'username': ['dream'], 'password': ['22'], 'hobby': ['music', 'sport']}>
# (1)如果是普通的键值对数据,直接get(key)
username = data.get("username")
password = data.get("password")
# 虽然后端看到的数据是一个列表,但是发现前端页面上的路由不是三个
# http://127.0.0.1:8000/register/?username=&password=&hobby=music&shobby=port&hobby=swim
# 只能取到最后一个
# (2)如果是列表形式的数据 getlist(key)
hobby = data.getlist("hobby")
print(username)
print(password)
print(hobby)
# 【3】第三个方法:如果是POST请求,需要 request.POST 获取请求体数据
elif request.method == "POST":
data = request.POST
print(data) # <QueryDict: {'username': ['dream'], 'password': ['521'], 'hobby': ['music', 'sport', 'swim']}>
username = data.get("username")
password = data.get("password")
hobby = data.get("hobby")
print(username)
print(password)
print(hobby)
return render(request, "register.html")
(3)urls.py
from django.contrib import admin
from django.urls import path
from app01.views import index, home, register
urlpatterns = [
path('admin/', admin.site.urls),
# 注册路由和视图函数的映射关系
path("index/", index),
path("home/", home, name="home"),
path("register/", register)
]
【四】Django连接数据库
【1】Django自带一个数据
- 自带一个数据库sqlite3
# 在settings.py文件中
# 数据库的配置项
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
【2】Django连接MySQL数据库
(1)配置mysql参数
DATABASES = {
'default': {
# ENGINE :默认的引擎 mysql
'ENGINE': 'django.db.backends.mysql',
# HOST : 主机地址127.0.0.1/localhost
"HOST": "127.0.0.1",
# "PORT": 3306,
"PORT": 3306,
# USER: 用户名
"USER": "root",
# PASSWORD: 数据库密码
"PASSWORD":"123456",
# NAME : 数据库名字
"NAME" : "django_02",
# CHARSET: 默认编码集
"CHARSET" : "utf8mb4"
}
}
(2)启动Django报错
Did you install mysqlclient?
【3】启动mysql报错
(1)解决办法一
- 猴子补丁
- 可以放在任意位置的
__init__.py
文件中
import pymysql
pymysql.install_as_MySQLdb()
(2)下载第三方模块
- 3.x版本以后建议你使用 mysqlclient
pip install mysqlclient
- 运气
- win 电脑给力一点,安装就不会报错
- mac系统安装 mysqlclient 费劲
(3)win报错解决办法
- 访问 whl文件的官网
- https://pypi.org/project/mysqlclient/#files
pip install mysqlclient-2.2.4-cp310-cp310-win_amd64.whl
【五】Django中的ORM框架
【1】什么是ORM
- ORM是一种将对象与关系型数据库之间的映射的技术,主要实现了以下三个方面的功能:
- 数据库中的表映射为Python中的类
- 数据库中的字段映射为Python中的属性
- 数据库中的记录映射为Python中的实例
- ORM的主要优点是可以减少开发人员编写重复的SQL语句的时间和工作量,并且可以减少由于SQL语句的调整和更改所带来的错误。
【2】DjangoORM框架的优点
- 与其他ORM框架相比,Django ORM拥有以下优点:
- 简单易用:Django ORM的API非常简单,易于掌握和使用。
- 丰富的API:Django ORM提供了丰富的API来完成常见的数据库操作,如增删改查等,同时也支持高级查询和聚合查询等操作。
- 具有良好的扩展性:Django ORM可以与其他第三方库进行无缝集成,如Django REST framework、Django-Oscar等。
- 自动映射:Django ORM支持自动映射,开发者只需要定义数据库表的结构,就可以自动生成相应的Python类,从而减少开发过程中的重复代码量。
【3】ORM之建表操作
(1)在app下面的models.py文件中定义模型表
from djaogo.db import models
# Create your models here.
class User(models.Model):
# 数据库中的字段映射为Python中的属性
# 定义一个用户名: 字符串类型 长度
# Mysql中字符串类型的字段:char varchar(32)
# CharField: 字符串类型的字段
# max_LENGTH: 最大长度
# verbose_name: 注释
# help_text : 解释
username = models.CharField(max_length=32,verbose_name="用户名",help_text="这是一个用户名字段")
password = models.CharField(max_length=32)
# IntergerField:相当于Mysql中的int字段
age = models.IntegerField()
# FloatField: 相当于Mysql数据库中的float 字段
salary = models.FloatField()
(2)迁移文件
- 生成迁移文件
- 将操作记录记录在migrations文件夹
- 虽然文件夹内有相关文件,但是此时并没有同步到数据库中,所以数据库是没有数据的
- manage.py 执行相关命令
- 方式有两种
- 一种是 task 任务里面
- 一种是命令行
E:\PycharmProjects\djangoProject>python manage.py makemigrations
Migrations for 'app01':
app01\migrations\0001_initial.py
- Create model User
-
迁移文件生效
-
将操作同步到真正的数据库
-
只要修改了models中有关数据库相关的代码,就必须执行上面的数据库迁移命令
migrate 动词 migrations 名词
python manage.py migrate
- 数据库生效
【六】ORM操作之字段操作
【1】字段属性
(1)允许为空
- 在定义模型类的相应字段时,可以为该字段添加
null=True
属性以允许其值为None
或空字符串。
class MyModel(models.Model):
name = models.CharField(max_length=50, null=True) # 允许name字段为空
(2)指定默认值
- 设置字段的默认值可通过在字段定义时附加
default
参数实现。例如,给字段age
设置默认值为 18
class MyModel(models.Model):
age = models.IntegerField(default=18) # 默认年龄为18岁
【2】字段增加
- 要在 Django 模型表中增加新的字段,只需在相应的 Model 类中添加新字段及其类型和所需属性。
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True) # 新增一个自动记录创建时间的datetime字段
is_active = models.BooleanField(default=True) # 新增一个布尔类型字段,默认激活状态为True
【3】字段删除
- 要从模型表中删除字段,请直接在 Model 类中注释掉该字段或者将其完全移除。
- 不过,在生产环境中删除字段前请确保不会影响现有数据,因为这可能导致数据丢失或结构不一致。
class MyModel(models.Model):
name = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True) # 移除is_removed字段
【补充】
- 每次修改关于数据库字段的操作时,都要执行数据库的迁移相关操作
python manage.py makemigrations
python manage.py migrate
【七】ORM操作之数据操作
【1】增加
(1)语法
模型表名:object.create(字段名=字段值)
(2)示例
new_interface = MyModel.objects.create(
name="zhangsan",
age=25,
email="zhangsan@example.com"
)
【2】查询
(1)语法
- 获取到当前表中的全部数据
模型表名.object.all()
- 根据指定条件筛选数据
# 方式一
模型表名.objects.get(筛选字段名=筛选字段值)
# 方式二
模型表名.objects.filter(筛选字段名=筛选字段值)
- 去除指定条件的数据
模型表名.object.exclude(筛选字段名=筛选字段值)
(2)示例
# 获取表中所有数据
all_records = MyModel.objects.all()
# 根据特定条件筛选数据(方式一)
filtered_records = MyModel.objects.get(name="张三")
# 根据特定条件筛选数据(方式二)
# 查询包含"张"的所有name
filtered_records = MyModel.objects.filter(name__contains="张")
# 去除满足指定条件的数据
# 过滤掉所有年龄小于18岁的记录
excluded_records = MyModel.objects.exclude(age__lt=18)
【3】更改
(1)语法
# 方式一:先查询直接修改
模型表名.objects.filter(筛选字段名=筛选字段值).update(修改字段名=修改字段值)
# 方式二:先查询后修改
obj = 模型表名.objects.get(筛选字段名=筛选字段值)
obj.修改字段名=修改字段值
obj.save()
(2)示例
# 可以使用.filter() 和 .update() 方法批量更新符合条件的数据
# 所有年龄为25的记录年龄改为26
MyModel.objects.filter(age=25).update(age=26)
# 更新已有记录的值,可先通过查询获取对象实例后调用 .save() 方法
instance_to_update = MyModel.objects.get(name="张三")
instance_to_update.age = 26
instance_to_update.save()
【4】删除
(1)语法
# 方式一:删除需要先查询直接删除
模型表名.objects.filter(筛选字段名=筛选字段值).delete()
# 方式二:删除需要先查询再删除
instance_to_delete = MyModel.objects.get(筛选字段名=筛选字段值)
instance_to_delete.delete()
(2)示例
# 删除满足特定条件的记录,通常先通过查询获取对象实例再调用 .delete() 方法
instance_to_delete = MyModel.objects.get(name="张三")
instance_to_delete.delete()
# 可以使用 .filter() 方法批量删除
MyModel.objects.filter(name="李四").delete() # 删除所有名字为"李四"的记录
- 整理
from django.test import TestCase
# from app01.models import User
import os
# Create your tests here.
if __name__ == '__main__':
# 先导入一句话
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')
# 启动django
import django
django.setup()
from app01 import models
# 建表语句
# user_obj = models.User.objects.create(username="zhangsan", age=18, salary=1000, password="123")
# user_obj = models.User.objects.create(username="lisi", age=24, salary=1000, password="12")
# print(user_obj)
# 查询数据
# user_data = models.User.objects.all().values_list()
# print(user_data)
user_obj = models.User.objects.filter(username="zhangsan").first()
print(user_obj.username)
print(user_obj.age)
标签:入门,models,request,django,objects,import,Django,name
From: https://www.cnblogs.com/Fredette/p/18064689