一、插入、更新和删除

  • 调用一个模型类对象的save方法的时候就可以实现对模型类对应数据表的插入和更新。
  • 调用一个模型类对象的delete方法的时候就可以实现对模型类对应数据表数据的删除。

二、自关联

自关联是一种特殊的一对多的关系。

【案例】:显示广州市的上级地区和下级地区。

  • 地区表:id, atitle, aParent_id;
  • mysql终端中批量执行sql语句:source areas.sql;

第1步,添加地区模型类 app1/models.py

【关系属性】,代表当前地区的父级地区

class AreaInfo(models.Model):
'''地区模型类'''
# 地区名称
atitle = models.CharField(max_length=20)
# 【关系属性】,代表当前地区的父级地区
aParent = models.ForeignKey('self', null=True, blank=True) # class Meta:
# db_table = 'areas'

第2步,创建迁移,应用迁移创建对应表

D:\a\django-app\project1>py manage.py makemigrations
Migrations for 'app1':
app1\migrations\0004_auto_20200107_1148.py
- Alter field btitle on bookinfo
- Create model AreaInfo D:\a\django-app\project1>py manage.py migrate
Operations to perform:
Apply all migrations: admin, app1, auth, contenttypes, sessions
Running migrations:
Applying app1.0004_auto_20200107_1148... OK

查看表mysql命令窗:

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sakila |
| spiders |
| sys |
| test888 |
| world |
+--------------------+
8 rows in set (0.07 sec) mysql> use test888
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_test888 |
+----------------------------+
| app1_areainfo |
| app1_bookinfo |
| app1_heroinfo |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
13 rows in set (0.00 sec) mysql> desc app1_areainfo;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| atitle | varchar(20) | NO | | NULL | |
| aParent_id | int(11) | YES | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
3 rows in set (0.11 sec)

第3步,把地区数据表导入刚建的表

  • 表位置:q网盘\源码【area.sql】
  • 把例如:

    INSERT INTO app1_areainfo VALUES ('110000', '北京市', NULL);

    中的【app1_】改成 【对应的表名_】
进入sql命令窗:即可导入(路径不要有中文空格等)
use test888; #使用对应的表
source E:/pro_sql/test.sql; #导入数据 #执行效果: Query OK, 1 row affected (0.12 sec)

查询刚导入的表效果

select * from app1_areainfo;
| 659000 | 省直辖行政单位 | 650000 |
| 659001 | 石河子市 | 659000 |
| 659002 | 阿拉尔市 | 659000 |
| 659003 | 图木舒克市 | 659000 |
| 659004 | 五家渠市 | 659000 |
| 990000 | 新疆建设兵团 | NULL |
| 990100 | 第一师 | 990000 |
| 990200 | 第二师 | 990000 |
| 990300 | 第三师 | 990000 |
| 990400 | 第四师 | 990000 |
| 990500 | 第五师 | 990000 |
| 990600 | 第六师 | 990000 |
| 990700 | 第七师 | 990000 |
| 990800 | 第八师 | 990000 |
| 990900 | 第九师 | 990000 |
| 991000 | 第十师 | 990000 |
| 991100 | 建工师 | 990000 |
| 991200 | 第十二师 | 990000 |
| 991300 | 第十三师 | 990000 |
| 991400 | 第十四师 | 990000 |
+--------+-----------------------------------------------+------------+

第4步,app1/views.py 编辑对应函数,读取地区信息

from booktest.models import BookInfo,AreaInfo

def areas(request):
'''获取广州市的上级地区和下级地区'''
# 1.获取广州市的信息
area = AreaInfo.objects.get(atitle='广州市')
# 2.查询广州市的上级地区
parent = area.aParent
# 3.查询广州市的下级地址
children = area.areainfo_set.all()
# 使用模板
return render(request, 'app1/areas.html', {'area':area,'parent':parent, 'children':children})

第5步,配置app1/urls.py

展示对应省市区信息

from django.urls import path,re_path
from . import views urlpatterns=[
path('app1/',views.index),
path('books/',views.books), # 书详情页,通过url接收参数2种写法以下两种都可:
# path(r"detail/<int:bookId>",views.detail), #参数用尖括号包起来<>
re_path(r"^detail/(\d+)",views.detail), #参数必须要带括号 path('addInfo/',views.addInfo), #添加三国书 path(r'delete/<int:bid>',views.deleteInfo), #删除对应图书 path(r'area/',views.areas), #展示对应省市区信息
]

第6步,添加展示模板templates/app1/areas.html

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>自关联案例</title>
</head>
<body>
<h1>当前地区</h1>
{{ area.atitle }}<br/>
<h1>父级地区</h1>
{{ parent.atitle }}<br/>
<h1>下级地址</h1>
<ul>
{% for child in children %}
<li>{{ child.atitle }}</li>
{% endfor %}
</ul>
</body>
</html>

效果:

当前地区:

广州市

父级地区:

广东省

下级地址:

荔湾区

越秀区

海珠区

天河区

白云区

黄埔区

番禺区

花都区

南沙区

萝岗区

增城市

从化市

三、管理器(Manager)

问:BookInfo.objects.all()->objects是一个什么东西呢?

  • 答:objects是Django帮我自动生成的管理器对象,通过这个管理器可以实现对数据的查询。
  • objects是models.Manger类的一个对象。自定义管理器之后Django不再帮我们生成默认的objects管理器。
py manage.py shell
>>> from app1.models import BookInfo,HeroInfo
>>> type(BookInfo.objects)
<class 'django.db.models.manager.Manager'>

1 自定义模型管理器类

1)自定义一个管理器类,这个类继承models.Manger类。

2)再在具体的模型类里定义一个自定义管理器类的对象。

例1:在app1/models.py下定义一个管理器类

自定一个Manager类对象,管理器对象 book = models.Manager()

# 一类
# booktest2_bookinfo
class BookInfo(models.Model):
'''图书模型类'''
# 图书名称
btitle = models.CharField(max_length=20, db_column='title')
# 图书名字唯一
# btitle = models.CharField(max_length=20, unique=True, db_index=True)
# 价格,最大位数为10,小数为2
# bprice = models.DecimalField(max_digits=10, decimal_places=2)
# 出版日期
bpub_date = models.DateField()
# bpub_date = models.DateField(auto_now_add=True) # 创建时间
# bpub_date = models.DateField(auto_now=True) # 更新时间
# 阅读量
bread = models.IntegerField(default=0)
# 评论量
bcomment = models.IntegerField(default=0)
# 删除标记
isDelete = models.BooleanField(default=False) book = models.Manager() # 自定一个Manager类对象,管理器对象
#objects = BookInfoManager() # 自定义一个BookInfoManager类的对象

自定义管理器类之后再查询数据就变成如下

由:BookInfo.objects.all() 变:BookInfo.book.all()

>>> quit()

D:\a\django-app\project1>py manage.py shell
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD6
4)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app1.models import BookInfo >>> BookInfo.book.all() #【变】
<QuerySet [<BookInfo: 天龙八部>, <BookInfo: 三国演义>, <BookInfo: 红楼梦>, <Book
Info: 水浒传>]> >>> BookInfo.objects.all() #【原】
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'BookInfo' has no attribute 'objects'

2 自定义管理器类的应用场景

1)改变查询的结果集。

  • 比如调用BookInfo.books.all()返回的是没有删除的图书的数据。

例2:自定义Manager类

【1】自定义一个BookInfoManager类,实现查寻数据只返回isDelete=False(删除标记(伪删除))的书

【2】使用自定义的manager类

from django.db import models
# 设计和表对应的类,模型类 #【1】自定义一个BookInfoManager类
class BookInfoManager(models.Manager): #继承自models.Manager
'''图书模型管理器类'''
# 1.改变原有查询的结果集
def all(self):
# 1.调用父类的all方法,获取所有数据
books = super().all() # QuerySet
# 2.对books中的数据进行过滤
books = books.filter(isDelete=False)
# 返回books
return books # 一类
# 图书类
class BookInfo(models.Model):
'''图书模型类'''
# 图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
btitle = models.CharField(max_length=20,unique=True) #该字段不能重复,db_column='title'
# 出版日期,DateField说明是一个日期类型
bpub_date = models.DateField()
# 阅读量
bread = models.IntegerField(default=0)
# 评论量
bcomment = models.IntegerField(default=0)
# 删除标记
isDelete = models.BooleanField(default=False) #book = models.Manager() # 自定一个Manager类对象,管理器对象
objects = BookInfoManager() # 自定义一个BookInfoManager类的对象 【2】使用自定义的manager类

2)添加额外的方法。

  • 管理器类中定义一个方法帮我们操作模型类对应的数据表。
  • 使用self.model()就可以创建一个跟自定义管理器对应的模型类对象。

例3,把插入图书各个语句封装成一个BookInfo类的函数:

app1/models.py

1.【封装插入图书方法为BookInfo的函数】

2.使用时只需要 BookInfo.create_book(书标题,日期) 即可使用详情:

'''使用下一步封装的函数'''
from app1.models import BookInfo
BookInfo.create_book('test','1991-1-1')
book.btitle #(返回刚插入的标题)
'''定义类的封装插入图书函数'''
from django.db import models # 一类
# booktest2_bookinfo
class BookInfo(models.Model):
'''图书模型类'''
# 图书名称
btitle = models.CharField(max_length=20, db_column='title')
# 图书名字唯一
# btitle = models.CharField(max_length=20, unique=True, db_index=True)
# 价格,最大位数为10,小数为2
# bprice = models.DecimalField(max_digits=10, decimal_places=2)
# 出版日期
bpub_date = models.DateField()
# bpub_date = models.DateField(auto_now_add=True) # 创建时间
# bpub_date = models.DateField(auto_now=True) # 更新时间
# 阅读量
bread = models.IntegerField(default=0)
# 评论量
bcomment = models.IntegerField(default=0)
# 删除标记
isDelete = models.BooleanField(default=False) # book = models.Manager() # 自定一个Manager类对象,管理器对象
#objects = BookInfoManager() # 自定义一个BookInfoManager类的对象 @classmethod #【封装插入图书方法为BookInfo的函数】
def create_book(cls, btitle, bpub_date):#cls即类名
'''添加一本图书'''
# 创建一个cls类的对象
obj = cls()
obj.btitle = btitle
obj.bpub_date = bpub_date
# 添加进数据库
obj.save()
# 返回obj
return obj

例4,一般把增、删、改、查自定义函数写到Manger自定义类里

2.封装方法,操作模型类对应的数据表(增删改查)

class BookInfoManager(models.Manager):
'''图书模型管理器类'''
# 1.改变原有查询的结果集
def all(self):
# 1.调用父类的all方法,获取所有数据
books = super().all() # QuerySet
# 2.对books中的数据进行过滤
books = books.filter(isDelete=False)
# 返回books
return books # 2.封装方法,操作模型类对应的数据表(增删改查)
def create_book(self, btitle, bpub_date):
'''添加一本图书'''
# 1.创建一个图书对象
# 获取self所在的模型类
model_class = self.model
book = model_class()
# book = BookInfo()
book.btitle = btitle
book.bpub_date = bpub_date
# 2.添加进数据库
book.save()
# 3.返回book
return book

调用:

from app1.models import BookInfo

#必须通过关键字传参
BookInfo.objects.create(btitle='test3',bpub_ date='1990-10-10' )
<BookInfo:BookInfo object>

上一步写的自定义函数先注释掉:

    # @classmethod
# def create_book(cls, btitle, bpub_date):
# '''添加一本图书'''
# # 创建一个cls类的对象
# obj = cls()
# obj.btitle = btitle
# obj.bpub_date = bpub_date
# # 添加进数据库
# obj.save()
# # 返回obj
# return obj

小结:



【模型管理器对象】

  1. 改变原有查询的结果集。
  2. 封装方法,用户操作管理器对象所在模型类对应的数据表。

3. 模型管理器类、模型类间关系

四、元选项(指定表名)

Django默认生成的表名: 应用名小写_模型类名小写。

元选项:

需要在模型类中定义一个元类Meta,在里面定义一个类属性db_table就可以指定表名。

应用场景:应用名(app1)和表名不一致情形

【问题】比如对应用名不满意想换个别的名字,此时表名已经生成了,这时应该怎么办呢?

  • 【解决】就可通过元选项解决。

实战app1/models.py

【1】指定表的名字

class AreaInfo(models.Model):
'''地区模型类'''
# 地区名称
atitle = models.CharField(max_length=20)
# 关系属性,代表当前地区的父级地区
aParent = models.ForeignKey('self', null=True, blank=True) class Meta: #【1】指定表的名字
db_table = 'areas'

Django(十)模型:django模型类对数据库的:增/删/改/查、自关联、管理器、元选项(指定表名)的更多相关文章

  1. django ajax增 删 改 查

    具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...

  2. 怎样从C#中打开数据库并进行 增 删 改 查 操作

    首先 在C#中引用数据库的操作! (因为我们用的是SQLserver数据库,所以是SqlClient) using System.Data.SqlClient; 1:要实现对数据库的操作,我们必须先登 ...

  3. django单表操作 增 删 改 查

    一.实现:增.删.改.查 1.获取所有数据显示在页面上 model.Classes.object.all(),拿到数据后,渲染给前端;前端通过for循环的方式,取出数据. 目的:通过classes(班 ...

  4. 简单的php数据库操作类代码(增,删,改,查)

    这几天准备重新学习,梳理一下知识体系,同时按照功能模块划分做一些东西.所以.mysql的操作成为第一个要点.我写了一个简单的mysql操作类,实现数据的简单的增删改查功能. 数据库操纵基本流程为: 1 ...

  5. django 多对多 增 删 改 查

      一.通过url方式实现多对多的:增加,删除,编辑 代码目录: urls.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...

  6. django一对多 增 删 改 查

    实现一对多表查询功能 项目代码: models.py from django.db import models # Create your models here. class Classes(mod ...

  7. python学习-62 类属性的增 删 该 查

    类属性 1.类属性 类属性又称为静态变量,或者是静态数据.这些数据是与它们所属的类对象绑定的,不依赖于任何类实例. 2.增 删 改 查 class zoo: country = 'china' def ...

  8. Django基础五之django模型层之关联管理器

    class RelatedManager "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器.它存在于下面两种情况: ForeignKey关系的“另一边”.像这样: 1 ...

  9. day 57 Django基础五之django模型层之关联管理器

    Django基础五之django模型层之关联管理器   class RelatedManager "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器.它存在于下面两种情况 ...

随机推荐

  1. Codeforces #617 (Div. 3) D. Fight with Monsters(贪心,排序)

    There are nn monsters standing in a row numbered from 11 to nn . The ii -th monster has hihi health ...

  2. Python学习笔记002

    字符编码:把二进制字符翻译成字符 ASCII码表    256    一个字节,8个比特 支持中文: GB2312 GBK1.0 GB18030 BIG5(台湾) unicode UTF-8 开头定义 ...

  3. Android开发实例之miniTwitter登录界面的实现

    原文: http://www.jizhuomi.com/android/example/134.html 本文要演示的Android开发实例是如何完成一个Android中的miniTwitter登录界 ...

  4. mybatis typealias 问题

    最近在学mybatis  在一个简单的问题上却花了挺长时间 网上也没发现有类似的案例 故记录一下 在configuration里面 typealias 和 properties 同时用会出错 具体原因 ...

  5. Codeforces1300D. Aerodynamic

    本题题目有点绕,结合图例大概可知,P(x,y)是以点给出的一个凸包,T是一个点集合,也构成一个凸包,构成的方法就是将原点(0,0)在P(x,y)的边上跑,移动坐标轴,其构成的最远点是个凸包,我们可以画 ...

  6. Python 面试问答基础篇

    1.       Python是如何进行内存管理的? 答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制 一.对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对 ...

  7. 设计模式课程 设计模式精讲 2-4 UML类图讲解 对比讲解 demo

    1 主要内容 1.1 关联和依赖的对比 1.2 组合和聚合的对比 1.3 继承和实现的对比 1.4 各种关系代码实现demo 1 主要内容 1.1 关联和依赖的对比 关联是a类中存在b类对象,企鹅类中 ...

  8. 工具 - brackets

    常用插件 blueprint beta file tree view indent guidelines

  9. 【快学springboot】在springboot中写单元测试

    前言 很多公司都有写单元测试的硬性要求,在提交代码的时候,如果单测通不过或者说单元测试各种覆盖率不达标,会被拒绝合并代码.写单元测试,也是保证代码质量的一种方式. junit单元测试 相信绝大多数的J ...

  10. pytest+allure(pytest-allure-adaptor基于这个插件)设计定制化报告

    一:环境准备 1.python3.6 2.windows环境 3.pycharm 4.pytest-allure-adaptor 5.allure2.8.0 6.java1.8 pytest-allu ...