前戏

我们来完成一个图书管理系统的增删改查

表结构设计

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实现出版社增删改查的更多相关文章

  1. django -- ORM实现作者增删改查

    前戏 前面我们已经实现了出版社的增删改查,书的增删改查,书和出版社的对应关系.现在来写一下作者的增删改查和书的对应关系,那书和作者有什么关系呢?一个作者可以写多本书,一本书可以有多个作者,所以书和作者 ...

  2. django -- ORM实现图书增删改查

    表结构设计 上篇我们实现了出版社的增删改查,出版社数据表有两个字段id和name,那图书的表结构怎么设计呢?图书也要有一个主键id,还要有一个名称title,是哪个出版社的,要有个字段press和Pr ...

  3. Django ORM记录的增删改查结合web端

    模版语法分配变量 在views.py文件中定义一个视图函数show_data: def show_data(request): # 定义一个字典 并将它展示在前端HTML文件 user_dic = { ...

  4. [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]

    [Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...

  5. Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

    一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...

  6. Django之数据表增删改查

    Django数据增删改查: 上课代码 from django.shortcuts import render,HttpResponse # Create your views here. from a ...

  7. ORM多表增删改查

    一 创建多表 在models.py里创建4张表:Author(作者).AuthorDetail(作者详细信息).Publish(出版社).Book(书) 四张表关系为: (1)首先创建一对一关系.On ...

  8. 使用轻量级ORM Dapper进行增删改查

      项目背景 前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET.微软的EF.NH等.再跟经理讨论后,经理强调不要用Ef,NH做ORM,后期的sql优化不好做,公司 ...

  9. Django基于类的增删改查,简单逻辑都不用写

    Django是Python中一个非常牛逼的web框架,他帮我们做了很多事,里边也提前封装了很多牛逼的功能,用起来简直不要太爽,在写网站的过程中,增删改查这几个基本的功能我们是经常会用到,Django把 ...

随机推荐

  1. 【leetcode-152】 乘积最大子序列

    给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4]输出: 6解释: 子数组 [2,3] 有最大乘积 6.示例 2: 输 ...

  2. Spring aop的一些小知识点总结

    1 Spring的aop无法拦截静态方法 2 在 proxyTargetClass = false时 对于实现了接口的bean,则只有接口中的方法会被拦截: 对于没有实现任何接口的bean,publi ...

  3. JavaScaript学习笔记第(一)

    js由三部分组成,分别是ECMAScript.DOM.BOM 其中ECMAScript规定了js的语法 js是一门解释型语言.脚本语言.动态类型语言.基于对象语言 书写js代码和CSS一样,有三个书写 ...

  4. javascript 对象的方式解析url地址参数

    看到一个知识点,比如说给一个 url参数,让其解析里面的各个参数,以前我都是通过字符串分割来实现的.但是通过这样的方式比较麻烦,而且操作字符串容易出错.今天看到了一个更有效更快速的方式,就是通过对象来 ...

  5. 04 .NET CORE 2.2 使用OCELOT -- identity认证授权

    修改接口项目 在上次的项目基础上,分别修改两个api项目的startup.cs public void ConfigureServices(IServiceCollection services) { ...

  6. centos如何强行踢掉某登录用户

    linux是一个多用户操作系统,用户可以在不同的地方链接上LINUX服务器. 在系统中我们可以用w或者who来查看用户: [root@7273 ~]# who root pts/0 2019-04-1 ...

  7. php 读取excel 时间列

    用PHP做一个导入excel功能,发现读取excel时间列的时候总是数据不对,去网上查找了这个函数,转换了一下就好了,真尼玛迷茫了,什么情况,先记录一下,以后再研究吧. 函数如下: function ...

  8. 递归删除文件和文件夹(bat)

    递归删除当前目录下指定的文件和文件夹,使用了通配符,Win10下亲测有效,仅供参考!  Batch Code  123456   @echo off echo del file... for /r % ...

  9. php+Apache2+Nginx+Mysql

        Nginx         1.安装Nginx     sudo apt-get clean     sudo apt-get update     sudo apt-get install ...

  10. cs1.6 人物地址查询

    打开游戏 控制台命令 增加一个BOT:bot_add 增加一个警察:bot_add_ct 增加一个匪徒:bot_add_t 让BOT站在原地不动:bot_stop 1 "-"减号: ...