django框架的基本使用
django框架的基本介绍
静态文件配置
1.什么是静态文件
-
静态文件是一个在请求数据之前就准备好的数据资源,可以直接拿来使用的文件
-
比如:
- css文件
- js文件
- images文件
- other文件 第三方
ps: 在django中的静态文件夹需要自己配置,一般起名就是static
2.什么是动态文件
- 动态文件就是从数据库中获取的数据
- 比如:
- 用户名,密码,账户信息等等..
3.什么是静态文件配置?
- 静态文件配置是django中可以创建一个文件夹用来管理静态文件
- 一般取名为
static
4.如何配置静态文件
4.1 第一步: 先到settings.py文件下创建一个静态文件变量
-
STATICFILES_DIR = [
os.path.join(BASEDIR,"static"),
os.path.join(BASEDIR,"static2"),
]
4.2 第二步: 然后设置一个静态文件前缀接口
- STATIC_URL = "static"
- html文件中可以通过static这个名称访问到STATICFILES_DIR变量内的所有的静态文件
5.动态解析静态文件变量名
-
介绍:
- 如当你的产品经理要求你讲对应静态文件前缀接口,改了.你就需要到每个html文件下的引用了静态文件处的名称全部改成新的.
- 这样肯定是不符合的
- 所有我们可以让这个前缀接口变为一个动态的.html文件中通过动态解析即可.该前缀接口名,而不用动html文件
-
在html中的语法
request对象的方法
1.request对象
request对象是来自于wsgiref模块下面解析好的请求数据对象,可以通过对象.
属性的方法去拿到浏览器的数据
2.方法介绍
2.1 method 方法
- 获取请求对象方式
- 如: request.method ----> 可能返回的是get/post
- 注意返回的结果是一个大写的字符串类型 即
GET/POST
- 应用场景,我们可以通过对用户的不同请求,分配不同的处理结果
2.2 GET请求方法
- 获取到get请求的数据对象,具体为url?后面的数据参数
- request.GET.get() # 返回get请求对象的最后一个元素的值
- request.GET.getlist() # 返回get请求对象的全部元素的值
2.3 POST请求方法
前提: 在settins.py文件中将
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',
]
- 获取到post请求的数据对象,具体为在post请求内的普通内容数据(不包含文件)
- request.POST.get() # 返回post请求对象的最后一个元素的值
- request.POST.getlist() #返回post请求对象的全部元素的值
pycharm如何链接mysql
1.先找到对应的DataBase 数据库选项
- 一般在pycharm的右上方和左下方
如图:
方式1:右上角
方式2:左下角
2.点击链接mysql数据库选项
3.mysql数据库的基本配置 驱动安装
驱动安装在下方的load点击即可下载
配置成功后,测试通过
4.即可查看数据库中的信息
5.添加数据和同步数据
django如何链接mysql
1.第一步: 收到settings.py文件下的DADABASES变量下,将django默认的sqlsplits3修改成我们的mysql数据库
代码为:
settings.py文件下
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
"HOST": "127.0.0.1",
"PORT": 3306,
"USER": "root",
"PASSWORD": "jzd123",
"NAME": "db777",
"CHARSET": "utf8",
}
}
2.第二步: 将django默认使用的mysql由mysqldb改为pycharm
可以到应用下的__init__.py
也可以到项目下的__init__.py
文件下进行修改
代码如下:
我在项目下的__inti__.py
文件下添加
import pymysql
pymysql.install_as_MySqldb()
django orm 简介
1.什么是orm?
- orm: 全称 object relational mapping 对象关系映射
2.orm和sql的关系图
3.功能
- 通过orm实现对数据库的增删改查
- 为的就是使没有学习过sql的python程序员可以通过面向对象的知识对数据库进行操作
4.实现
- 通过modles.py模型中的类对应数据库中的一个表,一个对象对应一行记录,一个属性对应一个字段的值.
5.缺陷
- 既然是别封装好的,那么就必须得遵循他的使用方法
- 封装程度太高了,有时候sql语句的执行效率可能偏低,需要你自己去写sql语句优化
- 比如: 当查询一个很大数据的数据库表时,orm的查询效率可能就没那么高了.
django orm 使用
1.如何在models.py中使用orm
代码介绍
models.py文件
from django.db import models
# Create your models here.
class User(models.Model):
"""
类就相当于表
"""
# sql: id int primary key auto_increment
id = models.AutoField(primary_key=True, verbose_name="主键")
# sql: username varchar(16)
username = models.CharField(max_length=16)
# sql: pwd varchar(14)
pwd = models.CharField(max_length=14)
sex = models.CharField(max_length=15)
hobbies = models.CharField(max_length=64)
class Author(models.Model):
"""
由于一张表中必须要有一个主键字段 并且一般情况下都叫id字段
所以orm当你不定义主键字段的时候 orm会自动帮你创建一个名为id主键字段
也就意味着 后续我们在创建模型表的时候如果主键字段名没有额外的叫法 那么主键字段可以省略不写
"""
# username varchar(32)
username = models.CharField(max_length=32)
# password varchar(255)
password = models.CharField(max_length=255)
需要注意的是:
- AutoField 必须要指定primary_key=True,不然也会报错
- CharField 必须要指定一个max_length属性,不指定会直接报错
- 其中不定义主键,默认创建的主键为id,区别于mysql的隐藏主键
models下的参数介绍
AutoField(Field)
- int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True
注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models
class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)
class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field):
- 可以为空的布尔值
CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度
TextField(Field)
- 文本类型
EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字
UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]]
DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
FloatField(Field)
- 浮点型
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
BinaryField(Field)
- 二进制类型
#注意:这些操作,如果是直接用数据库操作语句进行添加的话,不会有报错或是警告之类的信息
#但是如果换到后台管理页面上,进行添加则会有相应的警告!
数据库迁移
第一步: 打开pycharm下面的终端
在Terminal终端下 > 代码为:
# 切记要切换到当前的目录下
python3 manage.py makemigrations
python3 manage.py migrate
在DataBase数据中查看
在应用下的migrations迁移文件夹下生成迁移数据记录
现在可以真正的操作orm了
字段的增删改查
增
-- 1.在执行了生成数据库迁移命令之后,在终端命令行中输入默认值
-- 2.字段设置可以为空(默认不能为空)
info = models.CharField(max_length=32,verbose_name="个人简介", null=True)
-- 3. 直接给字段设置指定默认值
info = models.CharField(max_length=32,verbose_name="个人简介", defalut="喜欢打土匪")
删
-- 直接注释掉对应的字段,然后执行数据库迁移命令(俩条)
# password = models.CharField(max_length=32,verbose_name="密码")
-- 注意: 删除的字段对应的数据也会被删除
改
-- 将要改的字段修改成你要修改的值,然后再数据库迁移即可
password = models.CharField(max_length=32,verbase_name="密码")
password = models.IntegerField(max_length=32,verbase_name="密码")
查
-- 你打开的models类中的字段数据就是数据库中的数据
数据的增删改查
增
-- 方式1: 使用 models自动创建数据
models.User.objects.create(**kwargs)
-- 方式2: 手动创建数据
user_obj = models.User(**kwargs)
user_obj.save()
查
-- filter(**kwargs) 就相当于 sql中的where语句,为关键字 什么等于什么时,可以传多个
user_queryset = modles.User.objects.filter(**kwargs)
-- 返回的user_queryset是一个QuerySet. 是一个类似于 列表套数据对象的数据类型 <QuerySet [<User: User object>, <User: User object>, ...]>
-- 查询单个数据的俩种方式
-- 方式1: 索引取值,不能有负数
user_obj = user_queryset[0] # 拿到第一个数据对象<User: User object>
-- 方式2: 推荐使用.first() 但是底层原理也是通过索引取值
user_obj = user_queryset.first() # 拿到第一个数据对象<User: User object>
-- 查询所有数据的2种方式
-- 方式1: filter()
user_obj = models.User.objects.filter()
-- 方法2: all() 推荐,更加见名知意
user_obj = models.User.objects.all()
改
-- 方式1:
'''
批量操作对象
只会更新指定的, 将filter查询出来的列表中的所有的对象全部更新
批量更新操作只修改被修改的字段
'''
moldels.User.objects.filter(**kwargs).update(**kwargs)
-- 方式2:
'''
单独操作对象
无论有或者没有就是执行更新,因此当字段特别多的时候效率会非常低,
他会从头到尾将数据的所有字段全部更新一遍,无论改字段是否被修改.
'''
edit_obj = models.User.objects.filter(**kwargs).first()
edit_obj.username = username
edit_obj.pwd = pwd
edit_obj.save()
删
"""
真正的删除功能不能这么简单的让我们删除,会有一个二次确定的过程
而且要删除数据内部起始并不是真正的删除,我们通常会添加一个表示删除与否的字段来标识这个记录是否被删除了.
比如我们可以来个字段 is_delete 默认为0 删除了就成1
username password is_delete
jkey 123 0
liu 123 1
"""
-- 这里是简单的删除,直接删除记录了.
models.User.objects.filter(**kwargs).delete()
5.2 利用数据的查询和增加实现登录注册功能实例
-- 数据的查询: 登录功能例子
from app01 import models
username = request.POST.get('username')
res = models.User.objects.filter(username=username)
'''
res=[数据对象1, 数据对象2] 列表取值不能使用负数
补充: filter括号内可以带多个参数. 内部默认用and链接
'''
res = models.User.objects.filter(username=username).first() # 获取数据对象方式一: 推荐. 内部使用的是下面索引取值的的方式
user_obj = res[0] # 获取数据对象方式一: 推荐. 内部使用的是下面索引取值的的方式
user_obj = res.first() # 获取数据对象方式二: 与上面等同
print(user_obj.id) # 支持对象操作获取对应对象的id
print(user_obj.username)
print(user_obj.password)
# 数据的增加: 注册功能的例子
1. 准备注册页面
2. 获取用户输入
# 第一种: 利用models自动帮你保存
username = request.POST.get('username')
password = request.POST.get('password')
res = models.User.objects.create(username=username, password=password)
# res 返回值就是当前被创建的对象本身
# 第二种: 自己手动保存数据
user_obj = models.User(username=username, password=password)
user_obj.save()
5.3 利用数据的查改删实现对数据的编辑和删除功能实例
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index, name='index_name'),
url(r'^info/', views.info, name='info_name'),
url(r'^edit/', views.edit, name="edit_name"),
url(r'^delete/', views.delete),
url(r'^add/', views.add),
]
modles.py
from django.db import models
# Create your models here.
class User(models.Model):
username = models.CharField(max_length=16, blank=True, null=True)
pwd = models.CharField(max_length=14, blank=True, null=True)
sex = models.CharField(max_length=1, blank=True, null=True)
hobbies = models.CharField(max_length=12, blank=True, null=True)
class Meta:
managed = False
db_table = 'user'
views.py
from django.shortcuts import render, redirect, HttpResponse
# Create your views here.
from app01 import models
def index(request):
return render(request, 'index.html')
def info(request):
db_obj = models.User.objects.all()
return render(request, 'info.html', {"db_obj": db_obj})
def edit(request):
edit_id = request.GET.get("edit_id")
user_obj = models.User.objects.filter(id=edit_id).first()
print(user_obj)
if request.method == 'POST':
user_obj.id = request.POST.get('id')
user_obj.username = request.POST.get('username')
user_obj.sex = request.POST.get('sex')
user_obj.hobbies = request.POST.get('hobbies')
user_obj.save()
# models.User.objects.filter(id=edit_id).update(id=request.POST.get('id'),
# username=request.POST.get('username'), sex=request.POST.get('sex'), hobbies=request.POST.get('hobbies'))
return redirect('/info/')
return render(request, 'edit.html', {"user_obj": user_obj})
def delete(request):
delete_id = request.GET.get('delete_id')
models.User.objects.filter(id=delete_id).delete()
return redirect('/info/')
def add(request):
# user_obj = models.User.objects.all()
# for i in user_obj:
# if request.POST.get('id') == i.id:
# return HttpResponse("id已存在")
if request.method == 'POST':
try:
models.User.objects.create(id=request.POST.get('id'),
username=request.POST.get('username'),
pwd=request.POST.get('pwd'),
sex=request.POST.get('sex'),
hobbies=request.POST.get('hobbies'))
return redirect("/info/")
except Exception as e:
return HttpResponse("该id已存在")
return render(request, 'add.html')
templates模块
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.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>
<title>{% url 'index_name' %}</title>
</head>
<body>
<div class="container">
<h1 class="text-center">首页</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<a href="/info/">点击查看用户详情</a>
</div>
</div>
</div>
</body>
</html>
info.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.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>
<title>{% url 'info_name' %}</title>
</head>
<body>
<div class="container">
<h1 class="text-center"> 信息页</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>序号</th>
<th>名称</th>
<th>性别</th>
<th>爱好</th>
<th>功能</th>
</tr>
</thead>
<tbody>
{% for user in db_obj %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<td>{{ user.sex }}</td>
<td>{{ user.hobbies }}</td>
<td>
<a href="/edit/?edit_id={{ user.id }}">编辑</a>
<a href="/delete/?delete_id={{ user.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<button class="bg-warning"><a href="/add/">添加</a></button>
</div>
</div>
</div>
</body>
</html>
edit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.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>
<title>{% url 'edit_name' %}</title>
</head>
<body>
<div class="container">
<h1 class="text-center"> 编辑页 </h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>序号</th>
<th>名称</th>
<th>性别</th>
<th>爱好</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" value="{{ user_obj.id }}" name="id"></td>
<td><input type="text" value="{{ user_obj.username }}" name="username"></td>
<td><input type="text" value="{{ user_obj.sex }}" name="sex"></td>
<td><input type="text" value="{{ user_obj.hobbies }}" name="hobbies"></td>
<td><input type="submit" value="提交"></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
</body>
</html>
add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.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>
<title>Title</title>
</head>
<body>
<div class="container">
<h1 class="text-center"> 编辑页 </h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>序号</th>
<th>名称</th>
<th>密码</th>
<th>性别</th>
<th>爱好</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="id"></td>
<td><input type="text" name="username"></td>
<td><input type="password" name="pwd"></td>
<td><input type="text" name="sex"></td>
<td><input type="text" name="hobbies"></td>
<td><input type="submit" value="提交"></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
</body>
</html>
6.如何在django orm中创建表关系
1.表关系分析
表与表之间的关系: 一对多 多对多 一对一 没有关系
判断关系的方法: 换位思考
用四张表举例: 图书表 出版社表 作者表 作者详情表
图书表 和 出版社 为一对多的关系, 外键字段建在查询比较多的一方
图书和作者是多对多的关系, 需要创建第三张表来专门存储
作者与作者详情表是一对一
ps: 创建表关系 先将基表创建出来, 然后 在添加外键字段,这里建表可以没有先后顺序, 不同于mysql中建立外键的创建表以及插入记录的先后顺序
创建表关系
book | |||
---|---|---|---|
id | title | price | publish_id |
1 | python从入门到入土 | 21231 | 1 |
2 | django入门到废弃 | 23124 | 1 |
3 | 土匪是怎么炼成的 | 23123 | 2 |
author | ||
---|---|---|
id | name | age |
1 | jkey | 18 |
2 | 土匪 | 33 |
book2author | ||
---|---|---|
id | book_id | author_id |
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 2 |
4 | 3 | 3 |
publish | ||
---|---|---|
id | name | add |
1 | 北方出版社 | 北京 |
2 | 南方出版社 | 南京 |
author2detail | ||
---|---|---|
id | phone | info |
1 | 80080088 | 很有礼貌 |
2 | 88888888 | 逼王 |
补充知识
可以建立反同步的数据库,通过命令将数据库中的表变味orm中的class
命令
python3 manage.py inspectdb [表名]
ps: 没有填表名表示整个库中的所有表同步为class
举例
3.建立外键表关系基本语法
-- django orm 中建立表关系
一对一:
author_detail = models.OneToOneField(to="AuthorDetail") # to="AuthorDetail" 为要关联的表名
一对多:
publish = models.ForeignKey(to='Publish')
多对多:
publish = models.ManyToManyField(to="Book")
-- 拓展: 还可以有另外一种书写方式,不过这种方式必须放在被关联的类后,这里必须放在Publish定义之后
publish = models.ForeignKey(to=Publish)
-- 特点和注意事项
-- 1.先建立基表最后在建立外键关系,没有sql中建立外键必须先建立被关联的表,加入记录先插入被关联表这么一说,之间建立即可.
-- 2.django 1.x版本无需指定级联更新级联删除,默认就会帮你指定
-- 3.一对多,一对一无需在需要关键的字段后面加_id,默认会帮你加
-- 例如: publish --> publish_id
-- 4.一对多的表关系外键字段建立在多的一方
-- 5.多对多的表关系无需类似于sql语句中建立中间表,默认会将这个虚拟表创建
-- 6.一对一和多对多的表关系外键要建立在查询频率高的一方.
4.在 models.py 中创建以上模型类
models.py
from django.db import models
# Create your models here.
# 表与表之间的关系
class Book(models.Model):
title = models.CharField(max_length=225,verbose_name="书名")
# DecimalField 小数字段 max_length最大位数 decimal_places小数点精确位数
price = models.DecimalField(max_length=8,decimal_places=2, verbose_name="价格")
"""一对多
图书和出版社是一对多的关系,并且书是多的一方,所以外键要建立在书这边
ps: 如果字段对应的是ForeignKey 那么会字段名后面会加上_id
所以后面在定义外键字段就不用自己加_id了
"""
publish = models.ForeignKey(to="Publish") # 默认就是将出版社表中的外键字段做外键关联
"""多对多
图书和作者是多对多的关系,外键字段建在任何一方都可以,但是推荐加在搜寻频率高的一方
这里就创建在书这边了
"""
# authors为一个虚拟的字段,主要是告诉orm 书籍表和作者表是多对多的关系 orm会自动给你创建这个虚拟表
authors= models.ManyToManyField(to="Author")
class Publish(models.Model):
name = models.CharField(max_length=64,verbose_name="出版社名称")
addr = models.CharField(max_length=66, verbose_name="出版社地址")
class Author(models.Model):
name = models.CharField(max_length=225,verbose_name="作者姓名")
age = models.IntegerField(verbose_name="作者年龄")
"""一对一
作者和作者详情表为一对一的关系, 外键字段建在任何一方即可,但是推荐你添加到查询频率高的一方
"""
# OneToOneField 也会自动加上_id的后缀 千万别自己再加了
author_detail = models.OneToOneField(to="AuthorDetail")
class AuthorDetail(models.Model):
# BigIntegerField 为超过10位数字的字段
phone = models.BigIntegerField(verbose_name="作者电话号码")
addr = models.CharField(max_length=225, verbose_name="作者的住宅地址")
django请求生命周期流程图
总结
# 静态文件
-- 什么是静态文件?
-- 已经写好功能的文件,可以拿来就直接使用的文件
-- 例如:css,js,images,第三方
-- django怎么配置静态文件
-- 提示: django不会帮你设置好静态文件, 默认用的静态文件夹名为static
-- 到settins.py 中找到STATIC_URL,在其下方添加上
STATICFILES_DIR = [
os.path.join(BASEDIR,'static'),
os.path.join(BASEDIR,'static1')
]
# 如何解决接口前缀不断变化,html页面上路径的引用需要反复修改的问题
在templates管理的html文件中, 在head引用外部资源之前以如下书写方式:
{% load static %}
<script src="{% static '静态文件中的文件路径' %}"></script>
# from表单如果指定post请求, 需要注释一行代码:
settings.py -> MIDDLEWARE
# 'django.middleware.csrf.CsrfViewMiddleware',
# request对象的方法
request.method 返回大写字符串格式的当前请求方式
request.GET 返回URL中问好后面携带的参数. QueryDict对象: <QueryDict: {'username': ['egon'], 'hobbies': ['play', 'study']}>
request.POST 返回POST请求提交过来的普通键值对(不包含文件)
request.GET.get() 返回对象列表中最后一个的值 -> str
request.POST.get()
request.GET.getlist() 返回对象列表中所有的值 -> list
request.POST.getlist()
# django连接数据库
# django自带的数据库: db.sqlite3
# 配置更换
1. 配置数据库: 找到settings.py文件中的DATABASES输入如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'IP地址',
'PORT': 3306,
'USER': '登录用户',
'PASSWORD': '用户密码',
'NAME': '库名',
'CHARSET': 'utf8',
}
}
2. 代码声明: 使用pymysql替换django自带的数据库模块MySQLdb.
前提: 在项目文件夹下或者任意的应用文件夹下__init__.py中书写代码声明
import pymysql
pymysql.install_as_MySQLdb()
# django orm
# 什么是django orm
ORM 全称 object relational mapping 对象关系映射
功能: 通过ORM实现对操作对象的操作模式来操作数据库中的数据
实现: 通过models中的类来对应数据库中的一个表,一个对象对应一个数据行,一个属性对应数据库中的一个字段
缺陷: 封装程度太高, 有时候会出现创建sql语句的效率问题.
# 使用django orm: 进入models.py中书写模型类
'''
1. 不指定默创建id主键
2. ChildField必须指定max_length
3. verbose_name 所有字段都有 对字段的描述
'''
# id int primary key auto_increment
models.AutoField(primary_key=True, verbose_name='主键')
# username varchar(32)
models.CharField(max_length=32, verbose_name='用户名')
# password varchar(255)
models.charField(max_length=255, verbose_name='密码')
# age int
models.IntegerField(verbose_name='年龄')
# 数据库迁移命令
前提: 执行终端命令行当前路径一定要在项目文件夹下, 且配置了python的环境变量
生成数据库迁移记录, 记录到migrations文件夹中: python3 manage.py makemigrations
将数据迁移提交: python3 manage.py migrate
# orm字段的增删改查
增:
1. 在执行了生成数据库迁移记录命令之后在终端命令行中输入默认值
2. 直接为字段指定可以为空
username = models.CharField(max_length=32, null=True)
3. 为字段指定默认值
username = models.CharField(max_length=32, default='我是默认值')
删:
只要将需要删除的字段注释以后执行数据库迁移命令即可
注意(危险): 删除的字段对应的数据也将会删除
改:
直接在原来的字段的基础之上进行修改即可
# 数据的增查
增:
方式一: 使用models自动创建
user_obj = models.User.objects.create(**kwargs)
user_obj是一个QuerySet对象. 当前创建的对象本身
方式二: 手动创建
user_obj = models.User(**kwargs)
user_obj.save()
查:
user_obj_list = models.User.objects.filter(**kwargs)
user_obj_list是一个QuerySet对象. 它是一个列表套数据的对象: <QuerySet [<User: User object>, <User: User object>, <User: User object>]>
方式一: 索引取值. 不能使用负数.
user_obj = user_obj_list[0]
方式二: 推荐使用.first(). 但是其内部使用的也是通过索引取值
user_obj = user_obj_list.first()
# orm中创建外键
一对一:
author_detail = models.OneToOneField(to='AuthorDetail')
一对多:
publish = models.ForeignKey(to='Publish')
多对多:
authors = models.ManyToManyField(to='Book')