Navicat 可视化 或 者命令行.
创建library库并设置编码格式 utf8.
# 创建库设置编码
create database library character set utf8;
# 查看MySQL的编码
show variables like 'character_set_database';
# 查看自己创建的库 的编码
show create database library;
library目录下的setttings.py
# 0. 注销掉中间键第48行
# 'django.middleware.csrf.CsrfViewMiddleware',
# 1. 修改templates路径
'DIRS': [BASE_DIR, 'templates'],
启动程序报错:
UnicodeDecodeError:
'utf-8' codec can't decode byte 0xd2 in position 0: invalid continuation byte
电脑主机名是中文,修改电脑主机的名字.
详情:https://blog.csdn.net/shilei123456789666/article/details/79116219
# 2.连接MySQL数据库
DATABASES = {
'default': {
# 2.1 使用mysql
'ENGINE': 'django.db.backends.mysql',
# 2.2 ip地址
'HOST': '127.0.0.1',
# 2.3 端口号
'POST': 3306,
# 2.4 登入用户
'USER': 'root',
# 2.5 登入密码
'PASSWORD': '123',
# 2.6 连接的库
'NAME': 'library',
# 2.6 设置编码
'CHARSET': 'UTF8'
}
}
# 在app应下__init__.py下设置替换数据库
import pymysql
pymysql.install_as_MySQLdb()
表数据
book (书籍表)
id
title
price
publish_date
publish_id
1
Python
100.01
2021/1/1
1
2
MySQL
200.02
2021/2/2
2
3
Linux
300.03
2021/3/3
3
4
HTML
400.04
2021/4/4
1
publish(出版社表)
id
name
1
北京出版社
2
上海出版社
3
深圳出版社
book_author(虚拟表)
id
book_id
author_id
1
1
1
2
2
2
3
3
3
4
4
1
5
4
2
author(作者表)
id
name
age
author_id
1
kid
18
1
2
19
2
3
qz
18
3
authordetail(作者详情表)
id
phone
addr
1
110
北京
2
120
上海
3
130
深圳
先在models.py 中建立基础表
# 在model.py中添加表
from django.db import models
# 0. 书籍表
class Book(models.Model):
# 0.1 id 字段自动添加
# 0.2 书名
title = models.CharField(max_length=32, verbose_name='书名')
# 0.3 价格
price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
# 0.4 出版时间
publish_date = models.DateField(verbose_name='出版时间')
# 1. 出版社表
class Publish(models.Model):
# 1.1 id 字段自动添加
# 1.2 出版社名字
name = models.CharField(max_length=32, verbose_name='出版社名字')
# 1.3 出版社邮箱
email = models.EmailField(verbose_name='出版社邮箱')
# 2. 作者表
class Author(models.Model):
# 2.1 id 字段自动添加
# 2.2 作者姓名
name = models.CharField(max_length=32, verbose_name='作者姓名')
# 2.3 作者年龄
age = models.IntegerField(verbose_name='作者年龄')
# 3. 作者详情表
class Authordetail(models.Model):
# 3.1 id 字段自动添加
# 3.2 作者手机
phone = models.IntegerField(verbose_name='作者手机')
# 3.3 作者地址
addr = models.CharField(max_length=32, verbose_name='作者地址')
添加外键字端 (自动加后缀_id)
1. 出版社 一对多 书籍表 外键字段建立在多的一方书 籍表中 名为 publish
2. 作者表 多对多 书籍表 虚拟字段建立在查询频率高的一方 籍表中 名为 author
3. 作者表 一对一 作者详情表 外键字端建立在查询频率高的一方 作者表中 名为 authordetail
书籍表中:
ForeignKey(to='Publish') 一对多
ManyToManyField(to='Author') 多对多
作者表中:
OneToOneField(to='Authordetail') 一对一
to='表名' 表是class创建的表,表名首字符大写的要注意.
自动绑定表中主键字段.
# 0. 书籍表
class Book(models.Model):
# 0.1 id 字段自动添加
# 0.2 书名
title = models.CharField(max_length=32, verbose_name='书名')
# 0.3 价格
price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
# 0.4 出版时间
publish_date = models.DateField(verbose_name='出版时间')
# 0.5 外键字段 绑定 出版社
publish = models.ForeignKey(to='Publish', verbose_name='外键绑定出版社')
# 0.6 虚拟字段 创建第三张虚拟表
author = models.ManyToManyField(to='Author', verbose_name='虚拟字段创建第三张表')
# 2. 作者表
class Author(models.Model):
# 2.1 id 字段自动添加
# 2.2 作者姓名
name = models.CharField(max_length=32, verbose_name='作者姓名')
# 2.3 作者年龄
age = models.IntegerField(verbose_name='作者年龄')
# 2.4 外键字典 绑定 作者详情表
authordetail = models.OneToOneField(to='Authordetail', verbose_name='外键绑定作者详情表')
app01应用下 models.py 完整的代码
from django.db import models
# Create your models here.
# 0. 书籍表
class Book(models.Model):
# 0.1 id 字段自动添加
# 0.2 书名
title = models.CharField(max_length=32, verbose_name='书名')
# 0.3 价格
price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
# 0.4 出版时间
publish_date = models.DateField(verbose_name='出版时间')
# 0.5 外键字段 绑定 出版社
publish = models.ForeignKey(to='Publish', verbose_name='外键绑定出版社')
# 0.6 虚拟字段 创建第三张虚拟表
author = models.ManyToManyField(to='Author', verbose_name='虚拟字段创建第三张表')
# 0.7 打印对象时自动触发
def __str__(self):
return '%s %s %s %s %s %s' % (self.id, self.title, self.price, self.publish_date, self.publish, self.author)
# 1. 出版社表
class Publish(models.Model):
# 1.1 id 字段自动添加
# 1.2 出版社名字
name = models.CharField(max_length=32, verbose_name='出版社名字')
# 1.3 出版社邮箱
email = models.EmailField(verbose_name='出版社邮箱')
# 1.4 打印对象时自动触发
def __str__(self):
return '%s %s %s' % (self.id, self.name, self.email)
# 2. 作者表
class Author(models.Model):
# 2.1 id 字段自动添加
# 2.2 作者姓名
name = models.CharField(max_length=32, verbose_name='作者姓名')
# 2.3 作者年龄
age = models.IntegerField(verbose_name='作者年龄')
# 2.4 外键字典 绑定 作者详情表
authordetail = models.OneToOneField(to='Authordetail', verbose_name='外键绑定作者详情表')
# 1.5 打印对象时自动触发
def __str__(self):
return '%s %s %s %s' % (self.id, self.name, self.age, self.authordetail)
# 3. 作者详情表
class Authordetail(models.Model):
# 3.1 id 字段自动添加
# 3.2 作者手机
phone = models.IntegerField(verbose_name='作者手机')
# 3.3 作者地址
addr = models.CharField(max_length=32, verbose_name='作者地址')
# 3.4 打印对象时自动触发
def __str__(self):
return '%s %s %s' % (self.id, self.phone, self.addr)
# 在终端执行数据库迁移命令
python manage.py makemigrations
python manage.py migrate
0. 项目目录下创建 static目录
1. static目录下创建 js目录
2. 复制jQuery文件到 js目录中
3. 复制bootstrap-3.3.7-dist到static目录下
4. settings.py 配置文件中开放静态文件的路径
STATIC_URL = '/static/'
# 3. 开发静态文件目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
启动Django程序.
app01 应用tests.py测试文件
from django.test import TestCase
# Create your tests here.
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "library.settings")
import django
django.setup()
# 在这个代码会下面就可以测试django里面的单个py文件
# 所有代码必须等待环境准备完毕之后才能书写
from app01 import models # 这行代码是不允许在配置文件外面
不想写代码就手动录数据.
# tests.py测试文件中录数据
models.Book.objects.create(title='')
# 0. 为作者详情表录数据
models.Authordetail.objects.create(phone=110, addr='北京')
models.Authordetail.objects.create(phone=120, addr='上海')
models.Authordetail.objects.create(phone=130, addr='深圳')
# 1. 为作者表录数据
models.Author.objects.create(name='kid', age=18, authordetail_id=1)
models.Author.objects.create(name='qq', age=19, authordetail_id=2)
models.Author.objects.create(name='qz', age=20, authordetail_id=3)
# 2. 为出版社录数据
models.Publish.objects.create(name='北京出版社', email='[email protected]')
models.Publish.objects.create(name='上海出版社', email='[email protected]')
models.Publish.objects.create(name='深圳出版社', email='[email protected]')
# 3. 为图书表录数据
# 3.1 导入时间模块
import datetime
# 3.2 设置时间
date = datetime.date(2021, 1, 1)
models.Book.objects.create(title='Python', price=100.01, publish_date=date, publish_id=1)
date = datetime.date(2021, 2, 2)
models.Book.objects.create(title='MySQL', price=200.02, publish_date=date, publish_id=2)
date = datetime.date(2021, 3, 3)
models.Book.objects.create(title='Linux', price=300.03, publish_date=date, publish_id=3)
date = datetime.date(2022, 2, 18)
models.Book.objects.create(title='HTML', price=400.04, publish_date=date, publish_id=1)
# 4. 为第三张虚拟表添加数据
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.author.add(1)
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.add(2)
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.add(3)
book_obj = models.Book.objects.filter(pk=4).first()
book_obj.author.add(1, 2)
0. 在工程目录的总路由中配置路由
1. 在视图层中写视图函数
2. 主页面
127.0.0.1:8000 对应home主页
'^$' 匹配路径为空
# 项目目录下 urls.py
from django.conf.urls import url
from django.contrib import admin
# 0. 导入app01 的视图层
from app01 import views
urlpatterns = [
# 1.管理员后台 先注释掉
# url(r'^admin/', admin.site.urls),
# 2. 主页路由
url(r'^$', views.home)
]
主页视图函数返回主页面.
# app01 应用下的 views.py
# 0. 先导入 Django 三板斧
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
# 1. 主页视图
def home(request):
# 返回主页面
return render(request, 'home.html')
0. 在项目目录中templates目录下创建home.html页面
1. 导入jQuery与bootstrap文件
2. 这个页码是一个模板页面.在页面中划分三个区域,在继承的时候用于替换.
图书管理系统
{% load static %}
{% block css %}
{% endblock %}
{% block html %}
{% endblock %}
{% block js %}
{% endblock %}
栅格布局3-9分
.col-md-3
.col-md-9
栅格左边部分存放一个列表分组.
栅格右边部门放一个面板.
面板分面板标题和面板内容.
将面板内容作为替换区域.
图书管理系统
{% block html %}
{% endblock %}
面板中分两部分,
{% bloak html%}
上面放一个轮转图
下面放一个三个缩略图.
{% endbloak %}
轮转图
1. https://s2.loli.net/2022/03/10/CNJFHvDlquibBda.jpg
2. https://s2.loli.net/2022/03/10/AWzJVDgPKlc8OZt.jpg
3. https://s2.loli.net/2022/03/10/IZlAELwBqPFjspU.jpg
缩略图
1. https://s2.loli.net/2022/03/10/I4ziahsHbWCAkJU.jpg
2. https://s2.loli.net/2022/03/10/fFm9Lu2hkQRoJNg.jpg
3. https://s2.loli.net/2022/03/10/8ojETnzqRkLyG6h.jpg
为栅格设置一个占据全部视点的属性.
container-fluid值 设置用于 100% 宽度,占据全部视点的容器。
7. 图片
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbt7Y7lj-1647080624466)(https://s2.loli.net/2022/03/10/IZlAELwBqPFjspU.jpg)]
8. 完整代码
图书管理系统
{% load static %}
{% block css %}
{% endblock %}
{% block js %}
{% endblock %}
3. 图书列表程序
3.1 路由层
0. 127.0.0.1:8000/book/list 对应 book_list 书籍列表页面
1. '^book/list/' 匹配路径
2. 为路由起一个别名
# 工程目录下路由层 urls.py
url(r'^book_list/', views.book_list, name='book_list')
3.2 视图层
视图函数中
先读取数据库中的书籍数据
再与图书列表页面一同返回.
# app01 应用下的 views.py
# 2.2 导入 models 模块
from app01 import models
# 2. 图书列表
def book_list(request):
# 2.1获取图书表中的数据, 再文件开始处导入models.py
queryset = models.Book.objects.all()
# 2.3 返回book_list 页面 和 书籍表数据
return render(request, 'book_list.html', locals())
3.3 图书列表页面
0. 在项目目录中templates目录下创建book_list.html页面,并清空文件内容.
1. 继承模板home主页.
2. 模板语法获取前端传递的数据.
3. 表单中展示数据.
1. 继承模板
{% extends 'home.html' %}
{% block html %}
{% endblock %}
2. 表单标题
序号
编号
书名
作者
出版社
出版日期
价格
操作
1
书id号
唯一
可能有多个
唯一
唯一
唯一
编辑 删除
判断字段的信息是唯一的还是有多个.
3. 表单数据
1.序号
方式一: forloop.counter 获取值.
方式二
在后端统计图书的数量,做成一个迭代器.
想着后端next(),后端不支持,()的语法,就封装成一个类.
1.序列化就生成一个迭代器
2.调用方法返回next()取出的值
3.前端对象.方法取值.
# 2.4 图书序号
class BookNum(object):
def __init__(self, num):
# 2.4.1 先参数一个列表在__iter__ 变成迭代器
self.iter = [i for i in range(num)].__iter__()
def get_number(self):
# 2.4.2 next取值并返回
return next(self.iter)
# 2.4.5 生成一个对象放回给前端
# 应用下 tests.py 测试文件 获取所有数据
queryset = models.Book.objects.all()
for obj in queryset:
# 1. 获取 id
print(obj.pk)
# 2. 获取书名
print(obj.title)
# 3. 作者 需要通过外键去获取而且值可能是对个
for author_obj in obj.author.all():
print(author_obj.name)
# 4. 获取出版社 需要通过外键去获取
print(obj.publish.name)
# 5. 获取出版日期
print(obj.publish_date)
# 6. 获取书籍的价格
print(obj.price)
print(''.center(30, '='))
1
Python
kid
北京出版社
2021-01-01
100.01
==============================
2
MySQL
qq
上海出版社
2021-02-02
200.02
==============================
3
Linux
qz
深圳出版社
2021-03-03
300.03
==============================
4
HTML
kid
qq
北京出版社
2022-02-18
400.04
==============================
4. 创建表单
{% for author_obj in obj.author.all %}
{% if forloop.last %}
{{ author_obj.name }}
{% else%}
{{ author_obj.name }},
{% endif %}
{% endfor %}
{% extends 'home.html' %}
{% block html %}
书籍列表
序号
编号
书名
作者
出版社
出版时间
价格
操作
{% for obj in queryset %}
{{ forloop.counter}}
{{ obj.pk }}
{{ obj.title }}
{% for author_obj in obj.author.all %}
{% if forloop.last %}
{{ author_obj.name }}
{% else%}
{{ author_obj.name }},
{% endif %}
{% endfor %}
{{ obj.publish.name }}
{{ obj.publish_date|date:'Y-m-d' }}
{{ obj.price }}
编辑
删除
{% endfor %}
{% endblock %}
5. 模板中绑定地址
图书列表
4.添加书籍页面
4.1 路由层
0. 127.0.0.1:8000/book_add 对应 book_add 添加书籍页面
1. '^book/add/' 匹配路径
2. 为路由起一个别名
# 工程目录下路由层 urls.py
url(r'^book_add/', views.book_add, name='book_add')
4.2 视图层
视图函数中
0. 先读取数据库中的作者表和出版社表的数据.
1. 再与添加图书页面一同返回.
图书表中需要的信息
id(自增不用管)
title(书名) input标签 name='title'
price(价格) input name='price'
publish_date(出版时间) input type='date' name='publish_date'
外键 publish_id 需要 出版社的id select name='publish' option value='id编码' 展示文字信息
虚拟字段 author_id 需要 作者的id
添加书籍表 直接使用已经存在的作者 和 已经存在的出版社.
# 3. 添加书籍
def book_add(request):
# 3.1 获取出版社表的所有数据
publish_queryeset = models.Publish.objects.all()
# 3.2 获取作者表的所有数据
author_queryeset = models.Author.objects.all()
# 3.3 返回页面和表数据
return render(request, 'book_add.html', locals())
4.3 前端页面
1. 继承模板
0. 在项目目录中templates目录下创建book_add.html页面,并清空文件内容.
1. 继承模板home主页.
2. 模板语法获取前端传递的数据.
3. 写一个form表单 提交方式POST 在form表单中设置输入框
{% extends 'book_list.html' %}
{% block html %}
{% endblock %}
2. form表单
{% extends 'book_list.html' %}
{% block html %}
添加书籍
{% endblock %}
3. 模板中绑定地址
添加书籍
4. 写入数据库
0. 获取POST请求中的数据.
1. 获取书籍对象
2. 往书籍表中写数据
直接create 写的数据
id(自增不用管) title(书名) price(价格) publish_date(出版时间) 外键 publish_id
第三张虚拟表使用.add()写入数据
author_id
# 3. 添加书籍
def book_add(request):
# 3.1 获取出版社表的所有数据
publish_queryset = models.Publish.objects.all()
# 3.2 获取作者表的所有数据
author_queryset = models.Author.objects.all()
# 3.4 判断当前的请求方式
if request.method == 'POST':
# 3.5 获取表单的数据
post_obj = request.POST
# 值只有一个 POST.get('键') 取值
title = post_obj.get('title')
price = post_obj.get('price')
publish_date = post_obj.get('publish_date')
publish_id = post_obj.get('publish_id')
# 值可以用多个 POST.getlist('键') 取值 --> 是一个列表
author_id = post_obj.getlist('author_id')
# print(title, price, publish_date, publish_id, author_id)
# 3.6 将数据写入数据库中 一对多的数据写入和正常写入数据一样
book_obj = models.Book.objects.create(title=title, price=price, publish_date=publish_date, publish_id=publish_id)
# 为第三张表写入数据 * 以位置参数传递参数
book_obj.author.add(*author_id)
# 3.7 数据写入成功后 返回到主页面
return redirect('book_list')
# 3.3 返回页面和表数据
return render(request, 'book_add.html', locals())
5. 添加书籍
5. 编辑数据页面
在图书列表中点击修改进入到编辑页面,提交的get请求携带书籍数据的id.
后端通过书籍id获取对应的数据,再交给前端,编辑页面中展示需要修改的信息.
5.1 编辑绑定地址
book_list 中的编辑 绑定地址
提交的get请求携带书籍数据的id.
编辑
5.2 路由层
0. 127.0.0.1:8000/book_edit/数字 对应 book_edit 添加书籍页面
1. '^book_edit/(?Pd+)/' 匹配路径
2. 在路由中设置有名分组获取GET请求携带的数据.
* 通过url访问的时候需要在后面加上一个数字, 数字是书籍的主键id,不推荐直接访问.
# 工程目录下路由层 urls.py
url(r'^book_edit/(?Pd+)/', views.book_edit, name='book_edit')
5.3 视图层
# 4. 书籍表编辑
def book_edit(request, edit_id):
# 4.1 获取需要修改的书籍id
book_obj = models.Book.objects.filter(pk=edit_id).first()
# 4.2 获取出版社
publish_queryset = models.Publish.objects.all()
# 4.3 获取作者表数据
author_queryset = models.Author.objects.all()
# 4.4 返回编辑页面
return render(request, 'book_edit.html', locals())
5.3 前端页面
0. 表单的提交方式为post
1. 前端页面中 时间需要 |date:'Y-d-m' 冒号后面也不能有空格.
2. 为input设置 required="required" 必须填写信息,不能为空
```html
{% extends 'home.html' %}
{% block html %}
编辑书籍
{% endblock %}
5.4 问题
以前遇到的一个别人写的bug:
0. 图书列表中提交的数据是 a标签 编辑 url 的设置为 {% url 'book_edit' book.pk %}
1. 点击编辑后 跳转到book_edit的地址,后面携带的字符串的 book.pk
2. 路由匹配中正则只能匹配的是字符串类型数据, 有名分组获取到 book.pk 传给后端
3. 视图函数中使用 filter(pk = '字符串类型的 book.pk') 去数据库中匹配到数据 ORM 能转换为同一类型
4. 获取数据后locals() 传给前端,可以使用模板语法拿到.
5. 设置默认出版社的时候 {% if publish_obj.pk == edit_id %} 这样写就出错了
5.5 修改数据
获取POST请求携带的数据,更新到数据库中.
修改一对多和普通表的数据:
queryset对象.update()
修改第三张虚拟表:
queryset对象.first() --> 数据对象
数据对象.author.set([可迭代对象])
# 4. 书籍表编辑
def book_edit(request, edit_id):
# 4.5 判断当前请求方式
if request.method == 'POST':
# 4.6 获取POST请求的数据
post_obj = request.POST
# 值为单个
title = post_obj.get('title')
price = post_obj.get('price')
publish_date = post_obj.get('publish_date')
publish_id = post_obj.get('publish_id')
# 值可能有多个 值是一个列表
author_id = post_obj.getlist('author_id')
print(title, price, publish_date, publish_id, author_id, edit_id)
# 4.7 更新数据库
book_obj = models.Book.objects.filter(pk=edit_id)
# 一对多的数据写入和正常写入数据一样
book_obj.update(title=title, price=price, publish_date=publish_date, publish_id=publish_id)
# 修改第三张表的数据 set需要的就是一个可迭代对象
book_obj.first().author.set(author_id)
# 4.8 数据写入成功后 返回到主页面
return redirect('book_list')
# 4.1 获取需要修改的书籍id
book_obj = models.Book.objects.filter(pk=edit_id).first()
# 4.2 获取出版社
publish_queryset = models.Publish.objects.all()
# 4.3 获取作者表数据
author_queryset = models.Author.objects.all()
# 4.4 返回编辑页面
return render(request, 'book_edit.html', locals())
6. 删除数据
0. book_list中绑定删除键的页面跳转 携带书籍的主键
1. 路由中有有名分组获取删除之间的id并传给后端
2. 视图函数直接获取书籍列表对象然后通过获取的之间id删除该图书.
3. 删除数据后跳转到图书列表中
删除
# 6. 书籍表删除
url(r'^book_delete/(?Pd+)/', views.book_delete, name='book_delete'),
# app1应用下 views.py 视图函数
# 5. 删除数据
def book_delete(request, del_id):
# 5.1 通过书籍主键删除书籍
models.Book.objects.filter(pk=del_id).delete()
# 5.2 删除后跳转到图书列表中
return redirect('book_list')
7. 前端修改页面
home.html主页 83 84 行删除
写一个js替换body的背景颜色.
图书管理系统
{% load static %}
总结
写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于 java开发 的学习思路及方向。从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的 点击我的Gitee获取。
还有 高级java全套视频教程 java进阶架构师 视频+资料+代码+面试题!
全方面的java进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。