一、ORM

理解:
表 ---> 类
记录 ---> 对象
字段 ---> 对象的属性
如何使用ORM
1、先明确数据库
MYSQL(settings.py和__init.py)
2、去应用下的models.py中
# 1、先定义一个类
class User(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
# 2、执行数据库迁移命令(tools >>> run manage.py.py task )
python3 manage.py makemigrations
python3 manage.py migrate
"""
1、主键字段不写也可以 ORM会自动帮你添加上一个名叫id的主键
2、只要修改了models中与数据库相关的代码就需要执行迁移命令
3、增删改查记录,不用迁移
"""
注意
Fields字段被指定为模型类的类属性,是模型最重要的部分,也是模型唯一必须要有的部分,是用来定义数据库字段的。
Django对字段的命名设置了一些限制:
1、注意字段名不要选择与模型API冲突的名字,如clean、save、delete等
2、字段名不能是Python保留字。
pass = models.IntegerField()
# 错误,'pass'是保留字
3、由于Django查询语法的工作方式,所以字段名称中连续的两个下划线不能超过两个。
例如:
class Example(models.Model):
foo__bar = models.IntegerField()
# 错误,因字段'foo__bar'带有两个下划线
4、Django不允许字段名以"_"结尾。
class Example(models.Model):
# 数据库中字段名改为aaa__aaa,但查询时仍用aaa
aaa=models.CharField(max_length=10,db_column='aaa__aaa')
bbb=models.CharField(max_length=10,db_column='bbb_')
字段类型
AutoFiled
IntegerField
CharField
DateField
DateTimeField
#1、AutoField
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
#2、IntegerField
一个整数类型,范围在 -2147483648 to 2147483647。
#3、CharField
字符类型,必须提供max_length参数, max_length表示字符长度。
#4、DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
#5、DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
公共参数(均为可选)
primary_key
null 如果为True,Django将在数据库中将控制储存为NULL,默认为False
blank 默认为False,如果为True,则该字段允许为空
default 设置字段的默认值
unique 如果为True,则该字段必须是唯一的
db_index 如果为True,则该字段设置suoyin
db_column 指定数据对应的字段名
choices 将字段限制为选择给定的选项
help_text
二、ORM操作
1、 表操作
创建表名为 User 的表
from django.db import models
# Create your models here.
class User(models.Model):
pass
为User表定义字段
from django.db import models
# Create your models here.
class User(models.Model):
id = models.AutoField(verbose_name="编号",primary_key=True)
# id int primary key autu_increment comment="编号";
name = models.CharField(verbose_name="年龄",max_length=16)
# name varchar(16) comment="年龄";
pwd = models.IntegerField(verbose_name="密码")
# pwd int comment="密码";
def __str__(self):
return self.name # 打印对象的时候,返回这个字符串
在终端terminal输入:
python3 manage.py makemigrations app01 # 放入migrationgs文件夹
python3 manage.py migrate # 开始迁移到数据库
准备好表:
mysql> use dj2;
Database changed
mysql> select * from app01_user;
+----+------+-----+
| id | name | pwd |
+----+------+-----+
| 1 | yly | 666 |
| 2 | zpx | 111 |
| 3 | aaa | 222 |
| 4 | bbb | 333 |
+----+------+-----+
4 rows in set (0.00 sec)
2、ORM记录操作
查记录
写在其他地方,通常是写在views内,也可以在代码下方的Python console中测试。
查的结果为:列表内套对象
------------------------------------------------------------------
>>>from app01 import models
# 查询user表中所有的数据
>>>models.User.objects.all() # select * from app01_user;
<QuerySet [<User: yly>, <User: zpx>, <User: aaa>, <User: bbb>]>
# 查询id=1的数据
>>>models.User.objects.filter(id=1) # select * from app01_user where id=1;
<QuerySet [<User: yly>]>
# 查询name=yly的数据
>>>models.User.objects.filter(name="yly") # select * from app01_user where name="yly";
<QuerySet [<User: yly>]>
# 查询name=bbb并且pwd=333的数据
>>>models.User.objects.filter(name="bbb",pwd=333)
<QuerySet [<User: bbb>]>
"""
<QuerySet [<User: bbb>]>可以简单的认为,列表内套对象,可以通过列表索引取对象
"""
# 讲解:
>>>models.User.objects.all()
<QuerySet [<User: yly>, <User: zpx>, <User: aaa>, <User: bbb>]> # 就相当于列表里面套一个对象
>>>models.User.objects.all()[0] # 取列表的第一个对象 yly
<User: yly>
>>>obj_y = models.User.objects.all()[0]
>>>obj_y.name # 可以直接对象 点 属性,得到name字段值
'yly'
>>>obj_y.pwd # 可以直接对象 点 属性,得到pwd字段值
666
>>>obj_y.id
1
增记录
增记录 有返回结果,为该记录对象本身
------------------------------------------------------------------
>>>from app01 import models
>>>models.User.objects.create(name='jerry',password=567)
# insert into user(name,password) values('jerry',567)
# 返回值为当前新增数据对象
>>>obj_new = models.User.objects.create(name="zzz",pwd=999)
>>>obj_new.name
'zzz'
>>>obj_new.pwd
999
>>>obj_new.id
5
>>>obj_new.name="xxx"
>>>obj_new.save() # 对象调用save方法保存到数据库
改记录
1、其实上面的"增操作"已经涉及到了改,不过改有两种方式
2、改有批量
------------------------------------------------------------------
方法一: 值操作
>>>from app01 import models
>>>edit_obj = models.User.objects.filter(id=3)[0] # 取查到的列表的第一个对象
>>>edit_obj.name = 'mmm'
>>>edit_obj.save() # 提交
方法一: update函数操作
>>>models.User.objects.filter(name="yly").update(name="Lion_Yie")
# update app01_user set name="Lion_Yie" where name="yly";
1 # 返回的结果是改了几条数据,和pymysql差不多
>>>models.User.objects.filter(name="xxx").update(name="wahaha") # 批量改
3
删记录
删操作也有批量删
------------------------------------------------------------------
>>>from app01 import models
>>>models.User.objects.filter(id=5).delete()
# delete from app01_user where id=5;
三、Django微项目演示ORM操作
准备表:
mysql> select * from app01_user;
+----+----------+-----+
| id | name | pwd |
+----+----------+-----+
| 1 | Lion_Yie | 666 |
| 2 | zpx | 111 |
| 3 | aaa | 222 |
| 4 | bbb | 333 |
| 5 | wahaha | 0 |
| 6 | wahaha | 111 |
| 7 | wahaha | 222 |
+----+----------+-----+
7 rows in set (0.00 sec)
mysql> desc app01_user;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| pwd | int(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
需求:
1.查看当前所有表数据(前端展示) /home/
2.书写用户注册页面(前端展示) /register/
3.编辑用户数据
4.删除用户
文件:
---------------------------------"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'^home/', views.home),
url(r"^register/",views.register),
url(r"^edit/",views.edit),
url(r"^delete/",views.delete)
]
---------------------------------"views.py"-------------------------------------
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.
def home(request):
# 1、web发来get请求,返回一个html页面
if request.method == "GET":
user_data = models.User.objects.all()
return render(request,"home.html",locals())
def register(request):
if request.method == "POST":
web_username = request.POST.get("username")
web_pwd = request.POST.get("pwd")
# 比对用户名是否冲突
is_user_exits = models.User.objects.filter(name=web_username)
if is_user_exits:
return HttpResponse("用户已注册")
models.User.objects.create(name=web_username,pwd=web_pwd)
return redirect("/home/")
return render(request, "register.html")
def edit(request):
edit_id = request.GET.get("edit_id")
if request.method == "POST":
edit_name = request.POST.get("username")
edit_pwd = request.POST.get("password")
# 修改表数据
models.User.objects.filter(id = edit_id).update(name=edit_name,pwd=edit_pwd)
return redirect("/home/")
edit_obj = models.User.objects.filter(id=edit_id)[0]
return render(request,"edit.html",locals())
def delete(request):
if request.method == "GET":
d_id = request.GET.get("delete_id")
models.User.objects.filter(id=d_id).delete()
return redirect("/home/")
---------------------------------"home.html"-------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">用户数据展示</h1>
<div class="col-md-8 col-md-offset-2">
<a href="/register/" class="btn btn-danger btn-sm"> 注册 </a>
<table class="table-hover table-striped table">
<thead>
<tr>
<th>编号</th>
<th>用户名</th>
<th>密码</th>
<th>选项</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_data %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.name }}</td>
<td>{{ user_obj.pwd }}</td>
<td>
<a href="/edit/?edit_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a>
<a href="/delete/?delete_id={{ user_obj.id }}" class="btn btn-primary btn-xs">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
---------------------------------"edit.html"-------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">编辑用户</h1>
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<p>username:
<input type="text" name="username" class="form-control" value="{{ edit_obj.name }}">
</p>
<p>password:
<input type="text" name="password" class="form-control" value="{{edit_obj.pwd}}">
</p>
<input type="submit" value="编辑" class="btn btn-success btn-block">
</form>
</div>
</div>
</div>
</body>
</html>
---------------------------------"register.html"-------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container" style="border: rgba(0,12,255,0.96)">
<div class="row">
<h1 class="text-center" style="color: #ff5c7c">用户注册</h1>
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<p>username:
<input type="text" name="username" class="form-control">
</p>
<p>pwd:
<input type="password" name="pwd" class="form-control">
</p>
<p>
<input type="submit" value="注册" class="btn btn-block btn-danger">
</p>
</form>
</div>
</div>
</div>
</body>
</html>
五、建立表关系(ForeignKey)
一对多外键关系
"""在orm中 外键字段建在多的一方"""
多对多外键关系
"""在orm中 可以直接写在查询频率较高的表中(自动创建第三张表)"""
一对一外键关系
"""在orm中 直接写在查询频率较高的表中"""
# 一对多
publish = models.ForeignKey(to='Publish')
# 多对多
authors = models.ManyToManyField(to='Author') # 自动创建书籍和作者的第三张关系表
# 一对一
author_detail = models.OneToOneField(to='AuthorDetail')
"""
ForeignKey OneToOneField 会自动给字段加_id后缀
"""
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
# 一对多
publish = models.ForeignKey(to='Publish')
# 多对多
authors = models.ManyToManyField(to='Author') # 自动创建书籍和作者的第三张关系表
class Publish(models.Model):
title = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
# 一对一
author_detail = models.OneToOneField(to='AuthorDetail')
class AuthorDetail(models.Model):
addr = models.CharField(max_length=32)
phone = models.BigIntegerField()