django -- ORM实现出版社增删改查
前戏
我们来完成一个图书管理系统的增删改查
表结构设计
1. 出版社
id name
2. 作者
id name
3. 书
id title 出版社_id
4. 作者_书_关系表
id 书_id 作者_id
创建表
现在有个需求,当我们访问http://127.0.0.1:8080/press_list/这个网址时,django给我们返回所有的出版社名称,我们可以在models里创建一个press的类来生成数据表
class Press(models.Model):
id = models.AutoField(primary_key=True) # id主键
name = models.CharField(max_length=32) # 出版社名称
然后再Terminal里执行下面的两句代码:
python manage.py makemigrations
python manage.py migrate
然后我们去往数据库里手动插入几条数据,添加好了之后我们该干什么了呢?想一想我上篇文章写的和上上篇文章写的,我们在浏览器访问上面的url是不是django先去url.py里去找这个路径,那我们就去url.py里添加一个
url(r'^press_list/', views.press_list),
添加好了,这个函数是不是还没有,那在去views里添加一个press_list的函数,记得导入这个类
def press_list(request):
ret = Press.objects.all() # 查询所有的出版社
print(ret)
return HttpResponse('ok')
结果
<QuerySet [<Press: Press object>, <Press: Press object>, <Press: Press object>]>
打印出来的是一个对象,大家在学面向对象的时候记不记得有个魔术方法__str__,通常用法是把对象的值打印出来,我们在去Press类里添加下面的代码
# __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
class Foo(object):
def __str__(self):
return 'zouzou'
def eat(self):
print('we are eating...')
obj = Foo()
print(obj)
结果:zouzou
不会__str__方法的看这里
class Press(models.Model):
id = models.AutoField(primary_key=True) # id主键
name = models.CharField(max_length=32) # 出版社名称 def __str__(self):
return self.name
注意:
添加完__str__方法后不需要执行那两行命令,因为__str__方法对数据库没有影响
然后我们重新访问一下刚才的网站,看一下ret的值
<QuerySet [<Press: 清华出版社>, <Press: 北大出版社>, <Press: 复旦出版社>]>
这样就打印出了我们的出版社名称,结合上篇的ret[0].name就可以取到第一个值
print(ret[0].name)
print(ret[1].name)
print(ret[2].name)
这样我们就取到了三个出版社的名称,现在出版社的名称取到了,我们要给返回一个press_list的页面,而不是一个ok,在来改一下press_list的函数
def press_list(request):
ret = Press.objects.all() # 查询所有的出版社 return render(request,'press_list.html',{'ret':ret})
之前学了查询某个字段的值:
User.objects.filter(email=ema,pwd=password)
如果要查询所有的值用all
User.objects.all()
上面的{'ret':ret})在上篇里说过,是django的模版语言,上次是传了一个固定的值,这次我们是传了一个对象,里面暂时有三个值
创建html文件
函数有了,是不是差个press_list.html的文件,在去templates下新增一个press_list.html的文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1">
<thead>
<th>id</th>
<th>名称</th>
</thead>
<tbody>
{% for i in ret %}
<tr>
<td>{{ i.id}}</td>
<td>{{ i.name }}</td>
</tr>
{% endfor %}
</tbody> </table> </body>
</html>
press_list.html
代码解释:
{% for i in ret %}
<tr>
<td>{{ i.id}}</td>
<td>{{ i.name }}</td>
</tr>
{% endfor %}
这是django的模版语言里for循环的用法,之前我们是返回了一个值,用{{变量名}},现在我们是要取到所有的出版社,所以要用for循环,和python里的for循环一样,以{% for i in ret %}开始,以{% endfor %}结束,中间还是用{{变量名}}的方法取值
现在我们都已经配置好了,在去访问一下网址看看效果

我们在数据库里在加一条数据,也能展示在页面上,这样我们就完成了我们需要的功能
用ORM往数据库里新增数据
上面我们的数据都是我们手动在数据库里添加的,那怎么使用ORM往数据库里添加数据呢?使用
User.objects.create(name=value)
就可以往数据库里插入数据了,和上面的分析一样,先去url.py加上路由
url(r'^add_press/', views.add_press),
在去views里添加add_press函数
# 添加出版社的处理函数
def add_press(request):
if request.method == 'POST': # 表示用户要发数据
name = request.POST.get('name') # 获取用户填的出版社数据
Press.objects.create(name=name) # 将数据添加到数据库中
return redirect('/press_list/') # 跳转到出版社列表页面 return render(request,'add_press.html') # 表示获取页面
在去创建一个新增数据的html文件叫add_press.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/add_press/" method="post">
<input type="text" name="name">
<input type="submit">
</form> </body>
</html>
接下来我们访问http://127.0.0.1:8080/add_press/就可以实现在页面上往数据库里添加数据的功能了
用ORM从数据库里删除数据
我们已经完成了一个很low的往数据库里新增数据的功能,现在来完成一个删除的功能
分析:
删除数据我们根据什么来删,前面设计表的时候因为id是主键,所以我们可以根据id去删除数据,那么问题就来了,我们是不是要有一个删除的按钮。我们删除了数据之后,id是不是就不是按照顺序往上增加了,是不是要在前面加一个序号,删除之后序号也跟着改变呢。然后我们查询到数据,使用ORM里的方法删除数据
表名.objects.filter('列名').delete()
先去修改press_list.html的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/add_press/">添加出版社</a>
<table border="1">
<thead>
<th>序号</th>
<th>id</th>
<th>名称</th>
<th>操作</th>
</thead>
<tbody>
{% for i in ret %}
<tr>
<td >{{ forloop.counter }}</td> <!--循环,从1开始,每次加1-->
<td>{{ i.id}}</td>
<td>{{ i.name }}</td>
<td><a href="/delete_press/?id={{ i.id}}">删除</a></td> </tr>
{% endfor %}
</tbody> </table> </body>
</html>
代码解释:
<td >{{ forloop.counter }}</td> for循环,从1开始,如果想从0开始,则<td >{{ forloop.counter0 }}</td>
<td><a href="/delete_press/?id={{ i.id}}">删除</a></td> 我们可以通过url访问,当点击删除的时候,浏览器会往服务器发送一个url地址:http://127.0.0.1:8080/delete_press/?id=XX的网址。
然后我们去添加路由
url(r'^delete_press/', views.delete_press), # 删除出版社
在去添加对应的函数
# 删除出版社
def delete_press(request):
delete_id = request.GET.get('id')
Press.objects.filter(id=delete_id).delete()
return redirect('/press_list/')
这样当我们点击删除时,会删除掉对应的数据,并且重新访问press_list网页
Press.objects.filter(id=delete_id).delete()先查询数据,然后删除
用ORM从数据库里更改数据
先添加一个路由
url(r'^edit_press/', views.edit_press), # 编辑出版社
这里有两种方法可以实现编辑
第一种方法
先去添加一个函数
#编辑出版社
def edit_press(request):
if request.method=='POST':
#取出用户点击编辑之后的数据
edit_id = request.POST.get('id')
new_name = request.POST.get('name')
#去数据库修改对应的数据,先查询,在修改,在保存到数据库
edit_press_obj = Press.objects.get(id=edit_id)
edit_press_obj.name = new_name
edit_press_obj.save()
#让用户再次访问列表页面
return redirect('/press_list/') #获取要编辑的出版社
edit_id = request.GET.get('id')
#获取该出版社的信息
# ret = Press.objects.filter(id=edit_id)
ret = Press.objects.get(id=edit_id)
return render(request,'edit_press.html',{'press_obj':ret})
代码解释:
Press.objects.get(id=edit_id) 和filter都是查询数据的,不同的是get有且只能找到一个对象,否则会报错
他们两个返回的值都是一个对象,filter取值是
ret[0].name
就能取出name的值,而get取值是
ret.name
在去添加一个edit_press.html的文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/edit_press/" method="post">
<input type="text" name="id" value="{{ press_obj.id }}" style="display: none">
<input type="text" name="name" value="{{ press_obj.name }}">
<input type="submit" value="提交">
</form> </body>
</html>
edit_press.html
我们给服务器传了个id的值,把它设置了隐藏,这样服务器就能拿到我们的id值,才能去根据id唯一的修改数据
第二种方法
第二种方法和第一种差不多,我们在html文件里把id放到action里提交到服务器
修改edit_press.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/edit_press/?id={{ press_obj.id }}" method="post">
<input type="text" name="name" value="{{ press_obj.name }}">
<input type="submit" value="提交">
</form> </body>
</html>
edit_press.html
不同的是我们把id的值放在了action里传给了服务器,然后服务器就可以通过GET方法得到id值
修改edit_press函数
#编辑出版社
def edit_press(request):
# 获取要编辑的出版社id,因为是在url里,所以用GET
edit_id = request.GET.get('id') if request.method=='POST':
#取出用户点击编辑之后的数据
new_name = request.POST.get('name')
#去数据库修改对应的数据,先查询,在修改,在保存到数据库
edit_press_obj = Press.objects.get(id=edit_id)
edit_press_obj.name = new_name
edit_press_obj.save()
#让用户再次访问列表页面
return redirect('/press_list/') #获取该出版社的信息
ret = Press.objects.filter(id=edit_id)[0]
# ret = Press.objects.get(id=edit_id)
return render(request,'edit_press.html',{'press_obj':ret})
我们通过Press.objects.filter(id=edit_id)[0]获取到了值,如果使用的是Press.objects.get()就不需要再加[0],只有filter需要加[0]
这样我们也实现了编辑的功能
总结:
ORM的语句
查:
1. 类名.objects.all() --> 返回一个列表
2. 类名.objects.filter() --> 返回一个列表,取值要用[0],如果是循环,就不需要加[0]
3. 类名.objects.get() --> 返回一个对象,必须只能有一个,否则会报错
增:
类名.objects.create(name='') --> 创建一个对象,返回的就是刚创建的对象
删:
类名.objects.filter(id=).delete() --> 删除
改:
obj = 类名.objects.get(id='')
obj.name = '新值' --> 修改对象的属性(修改数据行某个字段的值)
obj.save() --> 把修改同步到数据库
模版语言
for循环
{% for i in ret %}
{{ i.属性 }}
{{ forloop.counter }} --> for循环从1开始计数
{{ forloop.counter0 }} --> for循环从0开始计数
{% endfor %}
django -- ORM实现出版社增删改查的更多相关文章
- django -- ORM实现作者增删改查
前戏 前面我们已经实现了出版社的增删改查,书的增删改查,书和出版社的对应关系.现在来写一下作者的增删改查和书的对应关系,那书和作者有什么关系呢?一个作者可以写多本书,一本书可以有多个作者,所以书和作者 ...
- django -- ORM实现图书增删改查
表结构设计 上篇我们实现了出版社的增删改查,出版社数据表有两个字段id和name,那图书的表结构怎么设计呢?图书也要有一个主键id,还要有一个名称title,是哪个出版社的,要有个字段press和Pr ...
- Django ORM记录的增删改查结合web端
模版语法分配变量 在views.py文件中定义一个视图函数show_data: def show_data(request): # 定义一个字典 并将它展示在前端HTML文件 user_dic = { ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查
一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...
- Django之数据表增删改查
Django数据增删改查: 上课代码 from django.shortcuts import render,HttpResponse # Create your views here. from a ...
- ORM多表增删改查
一 创建多表 在models.py里创建4张表:Author(作者).AuthorDetail(作者详细信息).Publish(出版社).Book(书) 四张表关系为: (1)首先创建一对一关系.On ...
- 使用轻量级ORM Dapper进行增删改查
项目背景 前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET.微软的EF.NH等.再跟经理讨论后,经理强调不要用Ef,NH做ORM,后期的sql优化不好做,公司 ...
- Django基于类的增删改查,简单逻辑都不用写
Django是Python中一个非常牛逼的web框架,他帮我们做了很多事,里边也提前封装了很多牛逼的功能,用起来简直不要太爽,在写网站的过程中,增删改查这几个基本的功能我们是经常会用到,Django把 ...
随机推荐
- Linux启动/停止/重启gitlab
# Start all GitLab components sudo gitlab-ctl start # Stop all GitLab components sudo gitlab-ctl sto ...
- 获取豆瓣电影数据(R与API获取网页数据)
一般成熟的网站都会有反爬虫策略,例如限制访问次数,限制访问 IP,动态显示数据等.爬虫和反爬虫就是一直相爱相杀地互相钳制.如果要通过爬虫来获取某些大型网站的数据,那是一件很费时费力的活.小白总遭遇过在 ...
- JavaIO学习:字节流
JavaIO流之字节流 字节流 抽象基类:InputStream,OutputStream. 字节流可以操作任何数据. 注意: 字符流使用的数组是字符数组,char[] chs : 字节流使用的数组是 ...
- 【ELK】elasticsearch使用bulk 导入批量的数据集文件报错:Validation Failed: 1: no requests added
执行命令如下: curl -XPOST http://192.168.6.16:9200/my_new_index/user/_bulk?pretty --data-binary @/cjf/es/e ...
- Java向MySQL新增记录时间误差问题
参考文档 https://www.jianshu.com/p/115861aad147 https://blog.csdn.net/ai932820942/article/details/845804 ...
- C# 中 ==和equals的区别
不想说太多,直接上代码,这两个就没什么联系,有自己独立的规则.联系在一起其实不利于记忆. 下面是测试代码 Console.WriteLine("--equals和==的区别--") ...
- select into 与 insert into select
1.select into select into 语句把一个表中的数据插入到另一个表中. 不需要创建临时表,在运行过程中自动创建. 基本语法: select * into #table_Name f ...
- ActiveMq C# 消息特性:延迟和定时消息投递
ActiveMQ from version 5.4 has an optional persistent scheduler built into the ActiveMQ message broke ...
- oracle 获取表\视图的列名
select COLUMN_NAME FROM user_col_comments WHERE TABLE_NAME='视图名' select COLUMN_NAME from all_tab_c ...
- Go语言(golang)新发布的1.13中的Error Wrapping深度分析
Go 1.13发布的功能还有一个值得深入研究的,就是对Error的增强,也是今天我们要分析的 Error Wrapping. 背景 做Go语言开发的,肯定经常用error,但是我们也知道error非常 ...