当前位置:
首页 > Python基础教程 >
-
Django框架(APP和ORM的使用)
12.3 APP
12.31 创建APP
一个Django项目可以分为很多个APP,用来隔离不同功能模块的代码
用命令行创建一个APP:
python3 manage.py startapp app01
创建好APP,记得告诉Django,app的名字,在settings.py中添加:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01',#或者'app01.apps.App01Config', ]
12.32 Django中的ORM
Django项目使用MySQL数据库
1.在Django项目的settings.py文件中,配置数据库连接信息:告诉Django连接哪个数据库
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "db6", # 需要自己手动先创建数据库 "USER": "root", "PASSWORD": "", "HOST": "127.0.0.1", "PORT": 3306 } }
2.Django默认使用的是 MySQLdb模块 连接数据库,但 MySQLdb在python3中不支持,所以:
在与Django项目同名的文件夹的__init__
.py文件中写如下代码,告诉Django使用pymysql模块连接MySQL数据库代替MySQLdb:
import pymysql pymysql.install_as_MySQLdb()
3.在app/models.py文件中定义类,一定要继承models.Model
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) # 自增主键 name = models.CharField(max_length=16) # varchar(16) pwd = models.CharField(max_length=128) # varchar(128) # 出版社 class Publisher(models.Model): id = models.AutoField(primary_key=True) # 自增主键 name = models.CharField(max_length=16) # varchar(16) # 出版社名称 #def __str__(self): #定义__str__是在打印表的对象时可以看到每一行的字段 # return (self.id,self.name) # 书籍 class Book(models.Model): id = models.AutoField(primary_key=True) # 自增的主键 title = models.CharField(max_length=32) # 书籍名称 varchar(32) publisher = models.ForeignKey(to="Publisher") # 外键关联Publisher这张表 # 作者 class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=16) books = models.ManyToManyField(to="Book") # ORM创建多对多字段,会自动在数据库中创建第三张表 id Author_id、Book_id
用命令行执行创建表的操作:
1. python3 manage.py makemigrations --> 将models.py的修改登记到小本本上
2. python3 manage.py migrate --> 将修改翻译成SQL语句,去数据库执行
4.在app/views.py文件中写urls.py中 /publisher_list/ 的对应函数publisher_list;/add_publisher/的对应函数add_publisher
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'^login/', views.login), url(r'^publisher_list/', views.publisher_list), # 展示出版社列表 url(r'^add_publisher/', views.add_publisher), # 添加出版社 url(r'^delete_publisher/', views.delete_publisher), # 删除出版社 url(r'^edit_publisher/', views.edit_publisher), # 编辑出版社 url(r'^book_list/', views.book_list), # 书籍列表 url(r'^add_book/', views.add_book), # 添加书籍 url(r'^delete_book/', views.delete_book # 删除书籍 url(r'^edit_book/', views.edit_book), # 编辑书籍 url(r'^author_list/', views.author_list), # 作者列表 url(r'^add_author/', views.add_author), # 添加作者 url(r'^delete_author/', views.delete_author), # 删除作者 url(r'^edit_author/', views.edit_author), # 编辑作者 url(r'^$', views.publisher_list) # 以上对应关系都找不到,就匹配出版社页面 ]
app/views.py:
12.321 有关出版社的函数逻辑
from django.shortcuts import HttpResponse, render, redirect from app01 import models # 显示出版社列表 def publisher_list(request): ret = models.Publisher.objects.all() # 从数据库中取出所有的数据对象列表 #print(ret) return render(request, "publisher_list.html", {"publisher_list": ret}) #添加出版社函数 def add_publisher(request): # 根据请求方法的不同,要做不同的事情,add_publisher.html使用POST方法 if request.method == "POST":#request.method获取的是请求的方法(GET、POST...必须是大写) #request.POST(字典)获取POST提交过来的全部数据 new_publisher_name = request.POST.get("publisher_name") models.Publisher.objects.create(name=new_publisher_name)#创建对象并封装属性(插入一行数据) #或者自己用类实例化一个对象:obj=models.Publisher(name=new_publisher_name) obj.save() #让用户跳转到publisher_list.html,显示新增数据后的publisher_list.html页面 return redirect("/publisher_list/") return render(request, "add_publisher.html") # 删除出版社函数 def delete_publisher(request): #print(request.method) #print(request.GET) delete_id = request.GET.get("id") #拿到用户要删除的出版社的id值 #print(delete_id) obj = models.Publisher.objects.get(id=delete_id)#根据id值得到对象 obj.delete() #将数据删除 return redirect("/publisher_list/") #让用户重新访问publisher_list.html更新页面 # 编辑出版社的函数 def edit_publisher(request): #edit_id = request.GET.get("id")如果用户提交使用URL拼接id,那么从URL里面取id参数request.GET.get("id") if request.method == "POST": #如果是post请求,表示用户已经编辑好了,向服务端提交修改后的新数据 edit_id = request.POST.get("edit_id") # 拿到已经修改的出版社id new_name = request.POST.get("name") # 拿到修改之后的出版社的名字 edit_obj = models.Publisher.objects.get(id=edit_id)#通过id找到数据行对象 edit_obj.name = new_name edit_obj.save() #保存修改,提交数据库 return redirect("/publisher_list/") # 修改成功,让用户跳转到出版社列表页面,更新页面 #如果不是post请求,则返回edit_publisher.html页面给用户修改出版社 edit_id = request.GET.get("id") #先获取编辑的出版社的ID值 obj = models.Publisher.objects.get(id=edit_id) #根据id值去数据库找对应的行数据对象 return render(request, "edit_publisher.html", {"publisher": obj})#将数据想要编辑的出版社显示出来,等待用户编辑
templates/publisher_list.html:
View Code
templates/add_publisher.html:
View Code
templates/edit_publisher.html:
View Code
12.322 有关书籍的函数逻辑
from django.shortcuts import HttpResponse, render, redirect from app01 import models # 书籍列表函数 def book_list(request): ret = models.Book.objects.all() #去数据库查询所有的书籍对象 return render(request, "book_list.html", {"book_list": ret})#将数据填充到页面上,发送给客户端 # 添加书籍函数 def add_book(request): if request.method == "POST": #如果是POST请求表示用户新添加了一本书籍和关联的出版社 book_name = request.POST.get("book_name") # 添加新书籍的名称 publisher_id = request.POST.get("publisher_id") # 添加新书籍关联的出版社id值 models.Book.objects.create(title=book_name, publisher_id=publisher_id) #publisher_obj = models.Publisher.objects.get(id=publisher_id)#根据id值先找到关联的出版社对象 #models.Book.objects.create(title=book_name, publisher=publisher_obj) return redirect("/book_list/") # 创建成功,让用户跳转到书籍列表页面,刷新数据 # 取到所有的出版社数据,在页面上渲染成select标签,供用户选择 ret = models.Publisher.objects.all() return render(request, "add_book.html", {"publisher_list": ret}) # 删除书籍的函数 def delete_book(request): delete_book_id = request.GET.get("id") # 从URL里面取到要删除的书籍的ID models.Book.objects.get(id=delete_book_id).delete()# 去数据库中删除 return redirect("/book_list/") # 删除成功,跳转到书籍列表页面,刷新数据 # 编辑书籍的函数 def edit_book(request): if request.method == "POST": # 如果是POST请求 表名是用户修改好了数据,向后端提交了 new_book_title = request.POST.get("book_title") # 取用户提交过来的数据 new_publisher_id = request.POST.get("publisher_id") book_id = request.GET.get("id") #获取URL中的当前编辑图书的id book_obj = models.Book.objects.get(id=book_id)# 根据id取出要编辑的书籍对象 book_obj.title = new_book_title book_obj.publisher_id = new_publisher_id book_obj.save() # 将修改保存到数据库 return redirect("/book_list/") # 修改完之后让用户跳转回书籍列表页面 # 返回一个让用户编辑数据的页面 edit_book_id = request.GET.get("id") # 取编辑的书籍的id值 edit_book_obj = models.Book.objects.get(id=edit_book_id) # 取到要编辑的书籍对象 publisher_list = models.Publisher.objects.all() # 去数据库查询目前所有的出版社数据 return render(request,"edit_book.html",{"book": edit_book_obj,"publisher_list":publisher_list})
templates/book_list.html:
<table class="table table-striped table-bordered"> <thead> <tr> <th>序号</th> <th>书籍名称</th> <th>出版社名称</th> <th>操作</th> </tr> </thead> <tbody> {% for book in book_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ book.title }}</td> <td>{{ book.publisher.name}}</td># book.publisher拿到的是外键(id)关联的出版社的行数据对象 <td class="text-center"> <a class="btn btn-info btn-sm" href="/edit_book/?id={{ book.id }}"> <i class="fa fa-pencil fa-fw" aria-hidden="true"></i> 编辑 </a> <a class="btn btn-danger btn-sm" href="/delete_book/?id={{ book.id }}"> <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i> 删除 </a> </td> </tr> {% endfor %} </tbody> </table>
templates/add_book.html:
<form class="form-horizontal" action="/add_book/" method="post"> <div class="form-group"> <label for="inputEmail3" class="col-sm-3 control-label">书籍名称</label> <div class="col-sm-9"><input type="text" class="form-control" id="inputEmail3" name="book_name" placeholder="书籍名称"> </div> </div> <div class="form-group"> <label for="inputEmail3" class="col-sm-3 control-label">出版社名称</label> <div class="col-sm-9"> <select class="form-control" name="publisher_id"> {% for publisher in publisher_list %} <option value="{{ publisher.id }}"> {{ publisher.name }} </option> {% endfor %} </select> </div
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式