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:

<body>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>出版社名称</th>
</tr>
</thead>
<tbody>
{% for publisher in publisher_list %}
<tr>
<td>{{ publisher.id }}</td> #{{ forloop.counter }计数表格中的数据条数,从而删除后更新id
<td>{{ publisher.name }}</td>
<td class="text-center">
<a class="btn btn-info btn-sm" href="/edit_publisher/?id={{ publisher.id }}">
<i class="fa fa-pencil fa-fw" aria-hidden="true"></i> 编辑 </a>
<a class="btn btn-danger btn-sm" href="/delete_publisher/?id={{ publisher.id }}">
<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>

templates/add_publisher.html:

<body>
<h1>添加新的出版社</h1>
<form action="/add_publisher/" method="post">
<input type="text" name="publisher_name">
<input type="submit" value="提交">
</form>
</body>

templates/edit_publisher.html:

#如果#action="/edit_publisher/?id={{ publisher.id }}"那么就从URL中用request.GET.get()取id参数
<form class="form-horizontal" action="/edit_publisher/" method="post">
<input type="text" name="edit_id" value="{{ publisher.id }}" class="hide">#将获取id的input框隐藏
<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="name"
placeholder="出版社名称" value="{{ publisher.name }}">#提交出版社名称
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
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>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9"><button type="submit" class="btn btn-default">提交</button> </div>
</div>
</form>

templates/edit_book.html:

#action=""此处使用默认URL,即继承之前的/edit_book/?id={{ book.id }}
#或者#action="/edit_publisher/?id={{ publisher.id }}"那么就从URL中用request.GET.get()取id参数
<form class="form-horizontal" action="" method="post">
#隐藏要编辑的书,发送id到后端,为了在后端找到要修改的图书,方便修改
#<input type="text" value="{{ book.id }}" name="book_id" class="hide"> #预先在输入框和下拉框显示要修改的图书名和出版社名
<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_title" value="{{ book.title }}" 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">
# 如果当前循环到的出版社和书关联的出版社相等,则添加selected,表示预先选中的
{% for publisher in publisher_list %}
{% if publisher == book.publisher %}
<option value="{{ publisher.id }}" selected>{{ publisher.name }}</option>
{% else %}
<option value="{{ publisher.id }}">{{ publisher.name }}</option>
{% endif %}
{% endfor %}
</select> </div>
</div>

<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
12.323 有关作者的函数逻辑
# 作者列表函数
def author_list(request):
authors = models.Author.objects.all() # 从数据库中查询所有的作者数据,在页面上展示出来
# author_obj = models.Author.objects.get(id=1)
# print(author_obj.books.all()) 表示id=1的作者写的所有书的对象
return render(request, "author_list.html", {"author_list": authors}) # 添加作者函数
def add_author(request):
if request.method == "POST":
new_author_name = request.POST.get("author_name") # 拿到新的作者姓名
models.Author.objects.create(name=new_author_name)# 去数据库中创建一个新的作者记录
return redirect("/author_list/") # 创建好作者之后,让用户跳转到作者列表页面
# 返回一个页面,让用户填写新的作者信息
return render(request, "add_author.html") # 删除作者函数
def delete_author(request):
delete_author_id = request.GET.get("id") # 从URL里面取到要删除的作者的ID
models.Author.objects.get(id=delete_author_id).delete()# 去数据库中找到该作者并删除
return redirect("/author_list/") # 删除成功后 跳转回作者列表页面 # 编辑作者函数
def edit_author(request):
if request.method == "POST": # 如果发送的是POST请求,应该拿到用户提交的数据
edit_author_id = request.POST.get("author_id") # 编辑的作者id
# 取新名字和新的书籍id
new_author_name = request.POST.get("author_name")
new_book_ids = request.POST.getlist("book_ids")
# 如果提交过来的数据是多个值(多选的select/多选的checkbox)则使用getlist取列表
# print(request.POST)
# print(edit_author_id, new_author_name, new_book_ids) # 去编辑作者以及对应的书籍
edit_author_obj = models.Author.objects.get(id=edit_author_id)# 拿到编辑的作者对象
edit_author_obj.name = new_author_name # 修改作者姓名
edit_author_obj.save()
# 修改作者写的书籍
edit_author_obj.books.set(new_book_ids) #通过新书id更换作者对应的书籍,并提交数据库
return redirect("/author_list/") # 修改完成之后,跳转到作者列表页面 # 返回一个页面,让用户编辑
edit_author_id = request.GET.get("id") # 从URL里面取到要编辑作者的id参数
edit_author_obj = models.Author.objects.get(id=edit_author_id)# 取到要编辑的作者对象
book_list = models.Book.objects.all() # 获取所有的书籍对象信息
return render(request,"edit_author.html",{"author": edit_author_obj,

templates/author_list.html:

 <div class="col-md-3 col-sm-6 pull-right add-btn">
<button data-target="#myModal" data-toggle="modal" class="btn btn-success pull-right">新增
</button>
<a href="/add_author/" class="btn btn-info pull-right">新页面添加 </a>
</div>

<table class="table table-striped table-bordered">
<thead>
<tr>
<th>序号</th>
<th>作者姓名</th>
<th>著作</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for author in author_list %}#{"author_list": authors}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ author.name }}</td>
<td> #在这一列展示这个作者关联的所有的书籍
{% for book in author.books.all %}#书籍对象的列表
{% if forloop.last %}
《{{ book.title }}》
{% else %}
《{{ book.title }}》,
{% endif %}
{% empty %}
暂无著作
{% endfor %}
</td>
<td class="text-center">
<a class="btn btn-info btn-sm" href="/edit_author/?id={{ author.id }}">
<i class="fa fa-pencil fa-fw" aria-hidden="true"></i>编辑 </a>
<a class="btn btn-danger btn-sm" href="/delete_author/?id={{ author.id }}">
<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>

templates/add_author.html:

<form class="form-horizontal" action="/add_author/" 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="author_name"
placeholder="作者姓名">
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>

templates/edit_author.html:

<form class="form-horizontal" action="" method="post">#action=""默认转到当前URL
<input type="text" value="{{ author.id }}" name="author_id" class="hide">
<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="author_name"
value="{{ author.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="book_ids" multiple>
{% for book in book_list %} #book_list 所有的书籍对象
#author:要编辑的作者,author.books.all:要编辑的作者的所有书籍对象
{% if book in author.books.all %} # 如果当前这本书在作者写的书里面
<option value="{{ book.id }}" selected>{{ book.title }}</option>
{% else %}
<option value="{{ book.id }}">{{ book.title }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>

python 之 Django框架(APP和ORM的使用)的更多相关文章

  1. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  2. 如何使用Python的Django框架创建自己的网站

    如何使用Python的Django框架创建自己的网站 Django建站主要分四步:1.创建Django项目,2.将网页模板移植到Django项目中,3.数据交互,4.数据库 1创建Django项目 本 ...

  3. Django框架之数据库ORM框架

    首先,我来介绍一下什么是ORM框架: O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思.在ORM框架中,它帮 ...

  4. Python的Django框架中的Cookie相关处理

    Python的Django框架中的Cookie相关处理 浏览器的开发人员在非常早的时候就已经意识到. HTTP's 的无状态会对Web开发人员带来非常大的问题,于是(cookies)应运而生. coo ...

  5. Python的Django框架中的Context使用

    Python的Django框架中的Context使用 近期整理些Python方面的知识,一旦你创建一个 Template 对象,你能够用 context 来传递数据给它. 一个context是一系列变 ...

  6. 将Python的Django框架与认证系统整合的方法

    将Python的Django框架与认证系统整合的方法 这篇文章主要介绍了将Python的Django框架与认证系统整合的方法,包括指定认证后台和编写认证后台等内容,需要的朋友可以参考下 将Django ...

  7. Python的Django框架中的URL配置与松耦合

    Python的Django框架中的URL配置与松耦合 用 python 处理一个文本时,想要删除其中中某一行,常规的思路是先把文件读入内存,在内存中修改后再写入源文件. 但如果要处理一个很大的文本,比 ...

  8. Django框架学习——python模拟Django框架(转载)

    原贴来源 http://wiki.woodpecker.org.cn/moin/ObpLovelyPython/AbtWebModules python实现web服务器 web开发首先要有web服务器 ...

  9. python 之 Django框架(Django框架简介、视图装饰器、request对象、Response对象)

    12.33 Django框架简介: MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器( ...

随机推荐

  1. LeetCode 741. Cherry Pickup

    原题链接在这里:https://leetcode.com/problems/cherry-pickup/ 题目: In a N x N grid representing a field of che ...

  2. pgloader 学习(一)支持的特性

    pgloader 是一个不错的多种格式数据同步到pg 的工具,pgloader 使用postrgresql 的copy 协议进行高效的数据同步处理 特性 加载文件到内容pg 多种数据源格式的支持 cs ...

  3. rpmlint 方便的rpm spec 以及rpm 文件检查工具

    rpmlint 可以方便的让我们检查rpm spec 的信息,给予我们提示以及改进,同时也支持对于rpm 文件处理 安装 yum install -y rpmlint 使用 spec 检查 rpmli ...

  4. Python json数据写入csv json excel文件

    一.写入 写入csv和json, 可以使用csv这个包写, 我这里没有使用, 并且把写csv和json的写到一起了 具体的代码就不解释了 def write_file(file_name, items ...

  5. 洛谷 P1522 牛的旅行 Cow Tours 题解

    P1522 牛的旅行 Cow Tours 题目描述 农民 John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧区通过任何路径都不 ...

  6. linux命令之------快捷键说明

    linux快捷键说明 (1)命令或目录补齐:Tab (2)遍历历史记录:history 上移:ctrl+p,下移:ctrl+n (3)光标移动 左移:ctrl+b:右移:ctrl+f:移到首部:ctr ...

  7. GoCN每日新闻(2019-10-16)

    GoCN每日新闻(2019-10-16) GoCN每日新闻(2019-10-16) 1. 持续的性能分析与优化 https://medium.com/@tvii/continuous-profilin ...

  8. 【2019.11.18】SDN阅读作业

    为什么需要SDN?SDN特点? 随着网络的快速发展,传统互联网出现了如传统网络配置复杂度高等诸多问题,这些问题说明网络架构需要革新,可编程网络的相关研究为 SDN 的产生提供了可参考的理论依据 SDN ...

  9. 刷题记录:[网鼎杯]Fakebook

    目录 刷题记录:[网鼎杯]Fakebook 一.涉及知识点 1.敏感文件泄露 2.sql注入 二.解题方法 刷题记录:[网鼎杯]Fakebook 题目复现链接:https://buuoj.cn/cha ...

  10. 刷题记录:[SUCTF 2019]EasySQL

    目录 刷题记录:[SUCTF 2019]EasySQL 一.涉及知识点 1.堆叠注入 2.set sql_mode=PIPES_AS_CONCAT;将||视为字符串的连接操作符而非或运算符 3.没有过 ...