s10_part3_django_project_library
s10_part3_django_project_library
- 前期内容总结:
- 图书管理系统数据库之表的设计
- 创建项目
- 修改settings.py及数据库相关设置
- 创建app01
- 创建model并初始化数据库
- 修改urls.py
- 在views.py中编写函数
- html模板文件(略)
- 表多对多关联
- 作者表在models中的实现
- 作者相关的函数
- 在urls.py增加作者相关URL
- 作者相关的html
前期内容总结:
1. 单表的增删改查
1. GET请求 URL传值
1. 格式
127.0.0.1:8000/delete_publisher/?name=alex&id=7
2. Django后端取值
request.GET --> 大字典
request.GET["name"]/request.GET["id"] --> key不存在就报错了
request.GET.get("name", "如果name没有就取这个默认值") --> 推荐用这个方法取值
2. POST方法提交的数据怎么取:
request.POST.get("key")
3. ORM操作
1. 删除
1. 先找到对象,调用对象的.delete()方法
publisher_obj = models.Publisher.objects.get(id=7)
publisher_obj.delete()
或者
models.Publisher.objects.get(id=7).delete()
2. 修改
1. 找到对象,通过修改对象的属性来修改数据库中指定字段的值,要保存
publisher_obj = models.Publisher.objects.get(id=7)
publisher_obj.name = "新的出版社名字"
publisher_obj.save() --> 把修改提交到数据库
4. GET和POST
1. GET请求:
1. GET请求携带的数据都拼在了URL上
2. GET请求携带的数据有长度限制 40k
2. POST请求
1. form表单提交数据
2. 上传文件
5. request相关的知识点
1. request.method
1. GET
2. POST
3.....
2. request.POST --> 所有和post请求相关的数据
3. request.GET --> 所有和GET请求相关的数据
图书管理系统数据库之表的设计
图书管理系统的三种角色
1. 出版社
2. 书
3. 作者
总结关系:
1. 一本书 只能 有一个出版社
2. 一本书 能有 多个作者
3. 一个作者 可著作 多本书
出版社和书: 一对多 --> 外键
书和作者: 多对多 --> 用第三张表做关联
表结构:
publisher:id,name
book: id,title,publisher_id
系统功能:
1. 查看书籍列表
2. 添加书籍
将所有的出版社在页面上以select标签的形式展示出来
3. 删除书籍
如何在后端获取要删除的是那一个书籍?
通过URL传参数的形式
4. 编辑书籍
将所有的出版社在页面上以select标签的形式展示出来
将当前编辑的书籍对象的书名和出版社在页面上展示出来
创建项目
执行如下shell命令创建django环境及项目
pipenv --python /usr/local/python3.6/bin/python3.6
pipenv shell
pip3 install django==1.11.1
pip3 install pymysql==0.9.2
django-admin startproject django_library
修改settings.py及数据库相关设置
修改django_library.django_library.init.py
import pymysql
pymysql.install_as_MySQLdb()
settings.py数据库配置相关
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': 'Pw123456',
'NAME': 'django_library',
}
}
在mysql中创建数据库名为:django_library
mysql -uroot -pPw123456 -e 'create database django_library default charset utf8;'
mysql -uroot -pPw123456 -e 'show databasee;'
settings.py模板相关
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
然后在项目目录下创建文件夹:templates,用于存放html模板文件
创建app01
cd django_library
python manage.py startapp app01
settings.py中注册app
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config' # 推荐的写法
]
目录结构:
django_library/
├── app01
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── django_library
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── templates
创建model并初始化数据库
# 图书管理系统, 书 作者 出版社
# 出版社
class Publisher(models.Model):
id = models.AutoField(primary_key=True) # 自增的ID主键
# 创建一个varchar(64)的唯一的不为空的字段
name = models.CharField(max_length=64, null=False, unique=True)
addr = models.CharField(max_length=128)
# 书
class Book(models.Model):
id = models.AutoField(primary_key=True) # 自增的ID主键
# 创建一个varchar(64)的唯一的不为空的字段
title = models.CharField(max_length=64, null=False, unique=True)
# 和出版社关联的外键字段
publisher = models.ForeignKey(to="Publisher")
python manage.py makemigrations
python manage.py migrate
修改urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# 默认存在的admin url
url(r'^admin/', admin.site.urls),
# 出版社相关的对应关系
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'^test/', views.test)
]
在views.py中编写函数
from django.shortcuts import HttpResponse, render, redirect
from app01 import models
# Create your views here.
# 展示出版社列表
def publisher_list(request):
# 去数据库查出所有的出版社,填充到HTML中,给用户返回
ret = models.Publisher.objects.all().order_by("id")
return render(request, "publisher_list.html", {"publisher_list": ret})
# 添加新的出版社
def add_publisher(request):
error_msg = ""
# 如果是POST请求,我就取到用户填写的数据
if request.method == "POST":
new_name = request.POST.get("publisher_name", None)
if new_name:
# 通过ORM去数据库里新建一条记录
models.Publisher.objects.create(name=new_name)
# 引导用户访问出版社列表页,查看是否添加成功 --> 跳转
return redirect("/publisher_list/")
else:
error_msg = "出版社名字不能为空!"
# 用户第一次来,我给他返回一个用来填写的HTML页面
return render(request, "add_publisher.html", {"error": error_msg})
# 删除出版社的函数
def delete_publisher(request):
print(request.GET)
print("=" * 120)
# 删除指定的数据
# 1. 从GET请求的参数里面拿到将要删除的数据的ID值
del_id = request.GET.get("id", None) # 字典取值,娶不到默认为None
# 如果能取到id值
if del_id:
# 去数据库删除当前id值的数据
# 根据id值查找到数据
del_obj = models.Publisher.objects.get(id=del_id)
# 删除
del_obj.delete()
# 返回删除后的页面,跳转到出版社的列表页,查看删除是否成功
return redirect("/publisher_list/")
else:
return HttpResponse("要删除的数据不存在!")
# 编辑出版社
def edit_publisher(request):
# 用户修改完出版社的名字,点击提交按钮,给我发来新的出版社名字
if request.method == "POST":
print(request.POST)
# 取新出版社名字
edit_id = request.POST.get("id")
new_name = request.POST.get("publisher_name")
# 更新出版社
# 根据id取到编辑的是哪个出版社
edit_publisher = models.Publisher.objects.get(id=edit_id)
edit_publisher.name = new_name
edit_publisher.save() # 把修改提交到数据库
# 跳转出版社列表页,查看是否修改成功
return redirect("/publisher_list/")
# 从GET请求的URL中取到id参数
edit_id = request.GET.get("id")
if edit_id:
# 获取到当前编辑的出版社对象
publisher_obj = models.Publisher.objects.get(id=edit_id)
return render(request, "edit_publisher.html", {"publisher": publisher_obj})
else:
return HttpResponse("编辑的出版社不存在!")
# 展示书的列表
def book_list(request):
# 去数据库中查询所有的书籍
all_book = models.Book.objects.all()
# 在HTML页面完成字符串替换(渲染数据)
return render(request, "book_list.html", {"all_book": all_book})
# 删除书籍
def delete_book(request):
# 从URL里面获取要删除的书籍的id值
delete_id = request.GET.get("id") # 从URL里面取数据
# 去删除数据库中删除指定id的数据
models.Book.objects.get(id=delete_id).delete()
# 返回书籍列表页面, 查看是否删除成功
return redirect("/book_list/")
# 添加书籍
def add_book(request):
if request.method == "POST":
print(request.POST)
print("=" * 120)
# {"book_title": "跟金老板学开车", "publisher": 9}
new_title = request.POST.get("book_title")
new_publisher_id = request.POST.get("publisher")
# 创建新书对象,自动提交
models.Book.objects.create(title=new_title, publisher_id=new_publisher_id)
# 用出版社对象创建
# publisher_obj = models.Publisher.objects.get(id=new_publisher_id)
# models.Book.objects.create(title=new_title, publisher=publisher_obj)
# 返回到书籍列表页
return redirect("/book_list/")
# 取到所有的出版社
ret = models.Publisher.objects.all()
return render(request, "add_book.html", {"publisher_list": ret})
# 编辑书籍
def edit_book(request):
if request.method == "POST":
# 从提交的数据里面取,书名和书关联的出版社
edit_id = request.POST.get("id")
new_title = request.POST.get("book_title")
new_publisher_id = request.POST.get("publisher")
# 更新
edit_book_obj = models.Book.objects.get(id=edit_id)
edit_book_obj.title = new_title # 更新书名
edit_book_obj.publisher_id = new_publisher_id # 更新书籍关联的出版社
# 将修改提交到数据库
edit_book_obj.save()
# 返回书籍列表页面,查看是否编辑成功
return redirect("/book_list/")
# 返回一个页面,让用户编辑书籍信息
# 取到编辑的书的id值
edit_id = request.GET.get("id")
# 根据id去数据库中把具体的书籍对象拿到
edit_book_obj = models.Book.objects.get(id=edit_id)
print(edit_book_obj.id)
print(edit_book_obj.title)
print(edit_book_obj.publisher) # 取到当前书籍对象关联的出版社对象
print(edit_book_obj.publisher_id) # 取到当前书籍对象关联的出版社的id值
ret = models.Publisher.objects.all()
return render(
request,
"edit_book.html",
{"publisher_list": ret, "book_obj": edit_book_obj}
)
def test(request):
print(request.GET)
print(request.GET.get("id"))
return HttpResponse("OK")
html模板文件(略)
表多对多关联
from part4_d64
publisher
id | name |
---|---|
1 | 第一出版社 |
2 | 第二出版社 |
book
id | title | publisher_id |
---|---|---|
1 | java | 1 |
2 | python | 2 |
author
id | name |
---|---|
1 | 小明 |
2 | 小白 |
author2book
id | author_id | book_id |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
作者表在models中的实现
# 作者表
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=16, null=False, unique=True)
# 告诉ORM 我这张表和book表是多对多的关联关系,ORM自动帮我生成了第三张表
book = models.ManyToManyField(to="Book")
def __str__(self):
return "<Author Object: {}>".format(self.name)
执行migrate
python manage.py makemigrations
python manage.py migrate
作者相关的函数
# 作者列表
def author_list(request):
#查询作者所有关联的书
# author_obj = models.Author.objects.get(id=1)
# print(author_obj.book.all())
# print("=" * 120)
# 查询所有的作者
all_author = models.Author.objects.all()
return render(request, "author_list.html", {"author_list": all_author})
# 添加作者
def add_author(request):
if request.method == "POST":
print("in post...")
# 取到提交的数据
new_author_name = request.POST.get("author_name")
# post提交的数据是多个值的时候一定会要用getlist,如多选的checkbox和多选的select
books = request.POST.getlist("books")
# 创建作者
new_author_obj = models.Author.objects.create(name=new_author_name)
# 把新作者和书籍建立对应关系,自动提交
new_author_obj.book.set(books)
# 跳转到作者列表页面,查看是否添加成功!
return redirect("/author_list/")
# 查询所有的书籍
ret = models.Book.objects.all()
return render(request, "add_author.html", {"book_list": ret})
# 删除作者
def delete_author(request):
# 从URL里面取到要删除的作者id
delete_id = request.GET.get("id")
#根据ID值取到要删除的作者对象,直接删除
# 1. 去作者表把作者删了
# 2. 去作者和书的关联表,把对应的关联记录删除了
models.Author.objects.get(id=delete_id).delete()
# 返回作者列表页面
return redirect("/author_list/")
# 编辑作者
def edit_author(request):
# 如果编辑完提交数据过来
if request.method == "POST":
# 拿到提交过来的编辑后的数据
edit_author_id = request.POST.get("author_id")
new_author_name = request.POST.get("author_name")
# 拿到编辑后作者关联的书籍信息
new_books = request.POST.getlist("books")
# 根据ID找到当前编辑的作者对象
edit_author_obj = models.Author.objects.get(id=edit_author_id)
# 更新作者的名字
edit_author_obj.name = new_author_name
# 更新作者关联的书的对应关系
edit_author_obj.book.set(new_books)
# 将修改提交到数据库
edit_author_obj.save()
# 返回作者列表页,查看是否编辑成功
return redirect("/author_list/")
# 从URL里面取要编辑的作者的id信息
edit_id = request.GET.get("id")
# 找到要编辑的作者对象
edit_author_obj = models.Author.objects.get(id=edit_id)
# 查询所有的书籍对象
ret = models.Book.objects.all()
return render(request, "edit_author.html", {"book_list": ret, "author": edit_author_obj})
在urls.py增加作者相关URL
# 作者相关的对应关系
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), # 编辑作者
作者相关的html
author_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>作者列表</title>
</head>
<body>
<a href="/add_author/">添加新的作者</a>
<h1>所有的作者</h1>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>名字</th>
<th>作品</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for author in author_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ author.id }}</td>
<td>{{ author.name }}</td>
<td>
{% for book in author.book.all %}
{{ book.title }}
{% endfor %}
</td>
<td>
<a href="/delete_author/?id={{ author.id }}">删除</a>
<a href="/edit_author/?id={{ author.id }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
add_author.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加作者</title>
</head>
<body>
<h1>添加作者</h1>
<form action="/add_author/" method="post">
<p>
作者姓名:<input type="text" name="author_name">
</p>
<p>
作品:
<select multiple name="books">
{% for book in book_list %}
<option value="{{ book.id }}">{{ book.title }}</option>
{% endfor %}
</select>
</p>
<p>
<input type="submit" value="提交">
</p>
</form>
</body>
</html>
edit_author.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑作者</title>
</head>
<body>
<h1>编辑作者</h1>
<form action="/edit_author/" method="post">
<input type="text" name="author_id" value="{{ author.id }}" style="display: none">
<p>
作者姓名:<input type="text" name="author_name" value="{{ author.name }}">
</p>
<p>
作品:
<select multiple name="books">
{% for book in book_list %}
{# 如果当前这本书 在 当前作者关联的所有书 里面 #}
{% if book in author.book.all %}
<option selected value="{{ book.id }}">{{ book.title }}</option>
{% else %}
<option value="{{ book.id }}">{{ book.title }}</option>{% endif %}
{% endfor %}
</select>
</p>
<p>
<input type="submit" value="提交">
</p>
</form>
</body>
</html>