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. php之大文件分段上传、断点续传

    前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...

  2. linux命令之------Tar解压缩

    Tar解压缩 作用:将解压缩后缀名为tar的压缩包 -f<备份文件>或—file=<备份文件>指定备份文件 -v或-verbose显示指令执行过程 -x或-extract或-g ...

  3. presto集成kerberos以及访问集成了kerberos的hive集群

    1.创建主体 注: 192.168.0.230 为单节点集群 192.168.4.50为kdc服务器 192.168.0.9为客户端 1.1.Kdc服务器创建主体 # kadmin.local -q ...

  4. 在Visual Studio中直接编译Fluent的UDF

    VS版本:Visual Studio 2013 Fluent版本:Fluent18.2 首先我们启动VS Studio中直接编译Fluent的UDF" title="在Visual ...

  5. Vue2.0 render: h => h(App)的解释

    render: h => h(App)是ES6的写法,其实就是如下内容的简写: render: function (createElement) { return createElement(A ...

  6. ubuntu之路——day12.1 不用tf和torch 只用python的numpy在较为底层的阶段实现简单神经网络

    首先感谢这位博主整理的Andrew Ng的deeplearning.ai的相关作业:https://blog.csdn.net/u013733326/article/details/79827273 ...

  7. Jmeter工具功能介绍

    可以去官方学习:http://jmeter.apache.org/ 1.可以修改语言 2.部分图标功能 新建 打开一个jmeter脚本 保存一个jmeter脚本 剪切 复制 粘贴 展开目录树 收起目录 ...

  8. java查看线程的堆栈信息

    通过使用jps 命令获取需要监控的进程的pid,然后使用jstack pid 命令查看线程的堆栈信息. 通过jstack 命令可以获取当前进程的所有线程信息. 每个线程堆中信息中,都可以查看到线程ID ...

  9. 从ReentrantLock的实现看AQS的原理及应用 可重入锁

    https://mp.weixin.qq.com/s/sA01gxC4EbgypCsQt5pVog

  10. http请求传参问题解决

    1.接口参数:使用form-data形式传参如果值太多就会报错误. 2.接口参数:使用form-data形式传参如果值太多就会报错误.这样前端可以传json就可以避免这样问题