一、ORM

ORM.png

理解:

  1. --->
  2. 记录 ---> 对象
  3. 字段 ---> 对象的属性

如何使用ORM

  1. 1、先明确数据库
  2. MYSQL(settings.py__init.py)
  3. 2、去应用下的models.py
  4. # 1、先定义一个类
  5. class User(models.Model):
  6. id = models.AutoField(primary_key=True)
  7. name = models.CharField(max_length=32)
  8. # 2、执行数据库迁移命令(tools >>> run manage.py.py task )
  9. python3 manage.py makemigrations
  10. python3 manage.py migrate
  11. """
  12. 1、主键字段不写也可以 ORM会自动帮你添加上一个名叫id的主键
  13. 2、只要修改了models中与数据库相关的代码就需要执行迁移命令
  14. 3、增删改查记录,不用迁移
  15. """

注意

  1. Fields字段被指定为模型类的类属性,是模型最重要的部分,也是模型唯一必须要有的部分,是用来定义数据库字段的。
  2. Django对字段的命名设置了一些限制:
  3. 1、注意字段名不要选择与模型API冲突的名字,如cleansavedelete
  4. 2、字段名不能是Python保留字。
  5. pass = models.IntegerField()
  6. # 错误,'pass'是保留字
  7. 3、由于Django查询语法的工作方式,所以字段名称中连续的两个下划线不能超过两个。
  8. 例如:
  9. class Example(models.Model):
  10. foo__bar = models.IntegerField()
  11. # 错误,因字段'foo__bar'带有两个下划线
  12. 4Django不允许字段名以"_"结尾。
  13. class Example(models.Model):
  14. # 数据库中字段名改为aaa__aaa,但查询时仍用aaa
  15. aaa=models.CharField(max_length=10,db_column='aaa__aaa')
  16. bbb=models.CharField(max_length=10,db_column='bbb_')

字段类型

  1. AutoFiled
  2. IntegerField
  3. CharField
  4. DateField
  5. DateTimeField
  1. #1、AutoField
  2. int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
  3. #2、IntegerField
  4. 一个整数类型,范围在 -2147483648 to 2147483647
  5. #3、CharField
  6. 字符类型,必须提供max_length参数, max_length表示字符长度。
  7. #4、DateField
  8. 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
  9. #5、DateTimeField
  10. 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例

公共参数(均为可选)

  1. primary_key
  2. null 如果为TrueDjango将在数据库中将控制储存为NULL,默认为False
  3. blank 默认为False,如果为True,则该字段允许为空
  4. default 设置字段的默认值
  5. unique 如果为True,则该字段必须是唯一的
  6. db_index 如果为True,则该字段设置suoyin
  7. db_column 指定数据对应的字段名
  8. choices 将字段限制为选择给定的选项
  9. help_text

二、ORM操作

1、 表操作

创建表名为 User 的表

  1. from django.db import models
  2. # Create your models here.
  3. class User(models.Model):
  4. pass

为User表定义字段

  1. from django.db import models
  2. # Create your models here.
  3. class User(models.Model):
  4. id = models.AutoField(verbose_name="编号",primary_key=True)
  5. # id int primary key autu_increment comment="编号";
  6. name = models.CharField(verbose_name="年龄",max_length=16)
  7. # name varchar(16) comment="年龄";
  8. pwd = models.IntegerField(verbose_name="密码")
  9. # pwd int comment="密码";
  10. def __str__(self):
  11. return self.name # 打印对象的时候,返回这个字符串
  12. 在终端terminal输入:
  13. python3 manage.py makemigrations app01 # 放入migrationgs文件夹
  14. python3 manage.py migrate # 开始迁移到数据库

准备好表:
  1. mysql> use dj2;
  2. Database changed
  3. mysql> select * from app01_user;
  4. +----+------+-----+
  5. | id | name | pwd |
  6. +----+------+-----+
  7. | 1 | yly | 666 |
  8. | 2 | zpx | 111 |
  9. | 3 | aaa | 222 |
  10. | 4 | bbb | 333 |
  11. +----+------+-----+
  12. 4 rows in set (0.00 sec)

2、ORM记录操作

查记录

  1. 写在其他地方,通常是写在views内,也可以在代码下方的Python console中测试。
  2. 查的结果为:列表内套对象
  3. ------------------------------------------------------------------
  4. >>>from app01 import models
  5. # 查询user表中所有的数据
  6. >>>models.User.objects.all() # select * from app01_user;
  7. <QuerySet [<User: yly>, <User: zpx>, <User: aaa>, <User: bbb>]>
  8. # 查询id=1的数据
  9. >>>models.User.objects.filter(id=1) # select * from app01_user where id=1;
  10. <QuerySet [<User: yly>]>
  11. # 查询name=yly的数据
  12. >>>models.User.objects.filter(name="yly") # select * from app01_user where name="yly";
  13. <QuerySet [<User: yly>]>
  14. # 查询name=bbb并且pwd=333的数据
  15. >>>models.User.objects.filter(name="bbb",pwd=333)
  16. <QuerySet [<User: bbb>]>
  17. """
  18. <QuerySet [<User: bbb>]>可以简单的认为,列表内套对象,可以通过列表索引取对象
  19. """
  20. # 讲解:
  21. >>>models.User.objects.all()
  22. <QuerySet [<User: yly>, <User: zpx>, <User: aaa>, <User: bbb>]> # 就相当于列表里面套一个对象
  23. >>>models.User.objects.all()[0] # 取列表的第一个对象 yly
  24. <User: yly>
  25. >>>obj_y = models.User.objects.all()[0]
  26. >>>obj_y.name # 可以直接对象 点 属性,得到name字段值
  27. 'yly'
  28. >>>obj_y.pwd # 可以直接对象 点 属性,得到pwd字段值
  29. 666
  30. >>>obj_y.id
  31. 1

增记录

  1. 增记录 有返回结果,为该记录对象本身
  2. ------------------------------------------------------------------
  3. >>>from app01 import models
  4. >>>models.User.objects.create(name='jerry',password=567)
  5. # insert into user(name,password) values('jerry',567)
  6. # 返回值为当前新增数据对象
  7. >>>obj_new = models.User.objects.create(name="zzz",pwd=999)
  8. >>>obj_new.name
  9. 'zzz'
  10. >>>obj_new.pwd
  11. 999
  12. >>>obj_new.id
  13. 5
  14. >>>obj_new.name="xxx"
  15. >>>obj_new.save() # 对象调用save方法保存到数据库

改记录

  1. 1、其实上面的"增操作"已经涉及到了改,不过改有两种方式
  2. 2、改有批量
  3. ------------------------------------------------------------------
  4. 方法一: 值操作
  5. >>>from app01 import models
  6. >>>edit_obj = models.User.objects.filter(id=3)[0] # 取查到的列表的第一个对象
  7. >>>edit_obj.name = 'mmm'
  8. >>>edit_obj.save() # 提交
  9. 方法一: update函数操作
  10. >>>models.User.objects.filter(name="yly").update(name="Lion_Yie")
  11. # update app01_user set name="Lion_Yie" where name="yly";
  12. 1 # 返回的结果是改了几条数据,和pymysql差不多
  13. >>>models.User.objects.filter(name="xxx").update(name="wahaha") # 批量改
  14. 3

删记录

  1. 删操作也有批量删
  2. ------------------------------------------------------------------
  3. >>>from app01 import models
  4. >>>models.User.objects.filter(id=5).delete()
  5. # delete from app01_user where id=5;

三、Django微项目演示ORM操作

准备表:

  1. mysql> select * from app01_user;
  2. +----+----------+-----+
  3. | id | name | pwd |
  4. +----+----------+-----+
  5. | 1 | Lion_Yie | 666 |
  6. | 2 | zpx | 111 |
  7. | 3 | aaa | 222 |
  8. | 4 | bbb | 333 |
  9. | 5 | wahaha | 0 |
  10. | 6 | wahaha | 111 |
  11. | 7 | wahaha | 222 |
  12. +----+----------+-----+
  13. 7 rows in set (0.00 sec)
  14. mysql> desc app01_user;
  15. +-------+-------------+------+-----+---------+----------------+
  16. | Field | Type | Null | Key | Default | Extra |
  17. +-------+-------------+------+-----+---------+----------------+
  18. | id | int(11) | NO | PRI | NULL | auto_increment |
  19. | name | varchar(16) | NO | | NULL | |
  20. | pwd | int(11) | NO | | NULL | |
  21. +-------+-------------+------+-----+---------+----------------+
  22. 3 rows in set (0.01 sec)

需求:

  1. 1.查看当前所有表数据(前端展示) /home/
  2. 2.书写用户注册页面(前端展示) /register/
  3. 3.编辑用户数据
  4. 4.删除用户

文件:

  1. ---------------------------------"urls.py"-------------------------------------
  2. from django.conf.urls import url
  3. from django.contrib import admin
  4. from app01 import views
  5. urlpatterns = [
  6. url(r'^admin/', admin.site.urls),
  7. url(r'^home/', views.home),
  8. url(r"^register/",views.register),
  9. url(r"^edit/",views.edit),
  10. url(r"^delete/",views.delete)
  11. ]
  12. ---------------------------------"views.py"-------------------------------------
  13. from django.shortcuts import render,HttpResponse,redirect
  14. from app01 import models
  15. # Create your views here.
  16. def home(request):
  17. # 1、web发来get请求,返回一个html页面
  18. if request.method == "GET":
  19. user_data = models.User.objects.all()
  20. return render(request,"home.html",locals())
  21. def register(request):
  22. if request.method == "POST":
  23. web_username = request.POST.get("username")
  24. web_pwd = request.POST.get("pwd")
  25. # 比对用户名是否冲突
  26. is_user_exits = models.User.objects.filter(name=web_username)
  27. if is_user_exits:
  28. return HttpResponse("用户已注册")
  29. models.User.objects.create(name=web_username,pwd=web_pwd)
  30. return redirect("/home/")
  31. return render(request, "register.html")
  32. def edit(request):
  33. edit_id = request.GET.get("edit_id")
  34. if request.method == "POST":
  35. edit_name = request.POST.get("username")
  36. edit_pwd = request.POST.get("password")
  37. # 修改表数据
  38. models.User.objects.filter(id = edit_id).update(name=edit_name,pwd=edit_pwd)
  39. return redirect("/home/")
  40. edit_obj = models.User.objects.filter(id=edit_id)[0]
  41. return render(request,"edit.html",locals())
  42. def delete(request):
  43. if request.method == "GET":
  44. d_id = request.GET.get("delete_id")
  45. models.User.objects.filter(id=d_id).delete()
  46. return redirect("/home/")
  47. ---------------------------------"home.html"-------------------------------------
  48. <!DOCTYPE html>
  49. <html lang="en">
  50. <head>
  51. <meta charset="UTF-8">
  52. <title>Title</title>
  53. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  54. {% load static %}
  55. <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
  56. </head>
  57. <body>
  58. <div class="container">
  59. <div class="row">
  60. <h1 class="text-center">用户数据展示</h1>
  61. <div class="col-md-8 col-md-offset-2">
  62. <a href="/register/" class="btn btn-danger btn-sm"> 注册 </a>
  63. <table class="table-hover table-striped table">
  64. <thead>
  65. <tr>
  66. <th>编号</th>
  67. <th>用户名</th>
  68. <th>密码</th>
  69. <th>选项</th>
  70. </tr>
  71. </thead>
  72. <tbody>
  73. {% for user_obj in user_data %}
  74. <tr>
  75. <td>{{ user_obj.id }}</td>
  76. <td>{{ user_obj.name }}</td>
  77. <td>{{ user_obj.pwd }}</td>
  78. <td>
  79. <a href="/edit/?edit_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a>
  80. <a href="/delete/?delete_id={{ user_obj.id }}" class="btn btn-primary btn-xs">删除</a>
  81. </td>
  82. </tr>
  83. {% endfor %}
  84. </tbody>
  85. </table>
  86. </div>
  87. </div>
  88. </div>
  89. </body>
  90. </html>
  91. ---------------------------------"edit.html"-------------------------------------
  92. <!DOCTYPE html>
  93. <html lang="en">
  94. <head>
  95. <meta charset="UTF-8">
  96. <title>Title</title>
  97. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  98. {% load static %}
  99. <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
  100. </head>
  101. <body>
  102. <div class="container">
  103. <div class="row">
  104. <h1 class="text-center">编辑用户</h1>
  105. <div class="col-md-8 col-md-offset-2">
  106. <form action="" method="post">
  107. <p>username:
  108. <input type="text" name="username" class="form-control" value="{{ edit_obj.name }}">
  109. </p>
  110. <p>password:
  111. <input type="text" name="password" class="form-control" value="{{edit_obj.pwd}}">
  112. </p>
  113. <input type="submit" value="编辑" class="btn btn-success btn-block">
  114. </form>
  115. </div>
  116. </div>
  117. </div>
  118. </body>
  119. </html>
  120. ---------------------------------"register.html"-------------------------------------
  121. <!DOCTYPE html>
  122. <html lang="en">
  123. <head>
  124. <meta charset="UTF-8">
  125. <title>Title</title>
  126. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  127. {% load static %}
  128. <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
  129. </head>
  130. <body>
  131. <div class="container" style="border: rgba(0,12,255,0.96)">
  132. <div class="row">
  133. <h1 class="text-center" style="color: #ff5c7c">用户注册</h1>
  134. <div class="col-md-8 col-md-offset-2">
  135. <form action="" method="post">
  136. <p>username:
  137. <input type="text" name="username" class="form-control">
  138. </p>
  139. <p>pwd:
  140. <input type="password" name="pwd" class="form-control">
  141. </p>
  142. <p>
  143. <input type="submit" value="注册" class="btn btn-block btn-danger">
  144. </p>
  145. </form>
  146. </div>
  147. </div>
  148. </div>
  149. </body>
  150. </html>

五、建立表关系(ForeignKey)

  1. 一对多外键关系
  2. """在orm中 外键字段建在多的一方"""
  3. 多对多外键关系
  4. """在orm中 可以直接写在查询频率较高的表中(自动创建第三张表)"""
  5. 一对一外键关系
  6. """在orm中 直接写在查询频率较高的表中"""
  7. # 一对多
  8. publish = models.ForeignKey(to='Publish')
  9. # 多对多
  10. authors = models.ManyToManyField(to='Author') # 自动创建书籍和作者的第三张关系表
  11. # 一对一
  12. author_detail = models.OneToOneField(to='AuthorDetail')
  13. """
  14. ForeignKey OneToOneField 会自动给字段加_id后缀
  15. """
  16. class Book(models.Model):
  17. title = models.CharField(max_length=32)
  18. price = models.DecimalField(max_digits=8,decimal_places=2)
  19. # 一对多
  20. publish = models.ForeignKey(to='Publish')
  21. # 多对多
  22. authors = models.ManyToManyField(to='Author') # 自动创建书籍和作者的第三张关系表
  23. class Publish(models.Model):
  24. title = models.CharField(max_length=32)
  25. class Author(models.Model):
  26. name = models.CharField(max_length=32)
  27. # 一对一
  28. author_detail = models.OneToOneField(to='AuthorDetail')
  29. class AuthorDetail(models.Model):
  30. addr = models.CharField(max_length=32)
  31. phone = models.BigIntegerField()