Django---图书管理系统,一对多(外键设置),__str__和__repr__的区别,进阶版项目说明简介.模版语言if ... else ..endif
Django---图书管理系统,一对多(外键设置),__str__和__repr__的区别,进阶版项目说明简介.模版语言if ... else ..endif
一丶__str__
和 __repr__
class Publish(models.Model):
pname = models.CharField(max_length=32, unique=True)
paddr = models.CharField(max_length=32)
# 这是调用 __str__ 方法打印的结果, __str__是让程序员看的
# 打印'对象'时,先找__str__方法,如果没有__str__方法,才找__repr__方法,在没有就去父类去找
def __str__(self):
return f'{self.pname}***{self.paddr}'
#这是调用 __repr__ 方法打印的结果, __repr__是让程序看的
#打印python默认数据类型时,直接调用的是__repr__方法
# 内置数据对象,直接调用 __repr__方法
def __repr__(self):
return f'{self.pname}--{self.paddr}'
# 让__repr__ 和 __str__相等 ,一般来说使用str就足够了
__repr__=__str__
区别图如下👇:
二丶Django中的一对多(外键约束)
在models.py文件下建立具有外键约束的表
from django.db import models
# '一'的一方:
class Publish(models.Model):
pname=models.CharField(max_length=32,unique=True)
paddr=models.CharField(max_length=32)
# '多'的一方:
class Book(models.Model):
bname=models.CharField(max_length=32,unique=True)
bprice=models.CharField(max_length=32)
pid=models.ForeignKey(to='Publish',on_delete=models.CASCADE) # 外键约束,
# 当执行完迁移命令时,pid字段在数据库中会是pid_id的存在
# 重点:
# 1. 数据库中的:pid_id是字段,对于类来说是属性. 可以直接放一个数值或其他类型的数据
# 2. 类中的pid字段则是一个对象,是关联外键的对象.使用时必须存放一个对象
# 参数说明:
to: # 关联外键的那张表,也就是类名
on_delete=None, # models.CASCADE 级联删除,
# models.SET(1) 将当前字段的值设置成1
# models.SET_DEFAULT 设置默认值, 需要设置default:default=11
# models.SET_NULL 设置为空,需要设置 : null=True
# models.DO_NOTHING 什么都不做,关联的数据删除后不影响当前字段的值
related_name=None, # 反向查询字段可以不用 表名小写,可以改名了
related_query_name=None,
limit_choices_to=None, # 限制关联字段的对象范围
parent_link=False,
to_field=None, # 被关联对象的用于关联的字段. 默认情况, Django 使用被关联对象的主键
db_constraint=True, # 这个就是保留跨表查询的便利(双下划线跨表查询```)
三丶进阶版一对多项目
说明:
# 两张表: 一张出版社表, 一张图书表
# 假设: 多本图书对应一个出版社, 图书表建立外键:如上建表👆
# 查图书表时,需要查看所属的出版社
# 添加图书时,需要查询所有的出版社,以下拉选择框的形式进行选择
# 更改时图书表需要,也需要查询所有的出版社,以下拉选择框的形式进行选择. 下拉框要有默认值(和数据库存在的数据一样)
# 删除,表设置了级联删除 on_delete=models.CASCADE, 删除出版社时,图书表中所对应的数据也一起被删除
查
#### 图书
def book_list(request):
all_books = models.Book.objects.all().order_by('pk')
return render(request, 'book_list.html', {'all_books': all_books})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书管理系统</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/dashboard.css">
<link rel="icon" href="/static/imgs/user.png">
<style>
.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th{
vertical-align: middle;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="/index/">主页</a></li>
<li><a href="#">配置</a></li>
<li><a href="#">简介</a></li>
<li><a href="#">帮助</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="搜索...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li><a href="/publish_list/">出版社管理 </a></li>
<li><a href="/book_list/">图书管理</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">图书列表</h2>
<div class="table-responsive">
<a href="/book_add/" class="btn btn-info btn-sm">添加图书</a>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>#</th>
<th>序号</th>
<th>图书编号</th>
<th>图书名称</th>
<th>图书价格</th>
<th>图书出版社</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- book 是图书对象, all_books是对象列表QuerySet -->
{% for book in all_books %}
<tr>
<td>
<input type="checkbox" >
</td>
<td>{{ forloop.counter }}</td>
<td>{{ book.pk }}</td>
<td>{{ book.bname }}</td>
<td>¥{{ book.bprice }}</td>
<!-- book是图书对象, .pid操作的关联的出版社对象 -->
<td>{{ book.pid.pname }}</td>
<td>
<a class="btn btn-warning btn-sm" href="/book_edit?pk={{ book.pk }}">编辑</a>
<a class="btn btn-danger btn-sm" href="/book_del?pk={{ book.pk }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
增
def book_add(request):
error, bn, bp, pub_sel = '', '', '', ''
all_publish = models.Publish.objects.all().order_by('pk')
if request.method == 'POST':
bn = request.POST.get('bname')
bp = request.POST.get('bprice')
pub_sel = request.POST.get('pub-sel')
print('zheshi', pub_sel)
if not bn:
error = '内容不允许为空'
elif models.Book.objects.filter(bname=bn):
error = '书籍已经存在'
else:
# 以为 数据库中的字段 pid_id 添加. 只是数值添加一一对应 . 推荐使用
models.Book.objects.create(bname=bn, bprice=bp, pid_id=pub_sel)
# 以orm操作类中的pid属性. 这个存的必须是一个对象,所有需要查出来一个对象.
# models.Book.objects.create(bname=bn, bprice=bp, pid=models.Publish.objects.filter(pk=pub_sel).first())
return redirect(to='/book_list/')
res = {'all_publish': all_publish, 'error': error, 'bname': bn, 'bprice': bp, }
print(res)
return render(request, 'book_add.html', res)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书管理系统</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/dashboard.css">
<link rel="icon" href="/static/imgs/user.png">
<style>
</style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="/index/">主页</a></li>
<li><a href="#">配置</a></li>
<li><a href="#">简介</a></li>
<li><a href="#">帮助</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="搜索...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li><a href="/publish_list/">出版社管理 </a></li>
<li><a href="/book_list/">图书管理</a></li>
</ul>
</div>
<div class="col-sm-8 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">图书添加</h2>
<div class="panel panel-success">
<div class="panel-heading ">图书添加</div>
<div class="panel-body">
<form class="form-horizontal" action="" method="post">
<div class="form-group">
<label for="bname" class="col-sm-2 control-label">图书名称</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="bname" value="{{ bname }}" name="bname"
placeholder="请填写图书名称">
</div>
<label class=" control-label text-danger" id="error">{{ error }}</label>
</div>
<div class="form-group">
<label for="bprice" class="col-sm-2 control-label">图书的价格</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="bprice" value="{{ bprice }}" name="bprice"
placeholder="请输入图书的价格">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">图书的出版社</label>
<div class="col-sm-6">
<select name="pub-sel" id="" class="form-control">
{% for publish in all_publish %}
<option value="{{ publish.pk }}">{{ publish.pname }}</option>
{% endfor %}
</select>
</div>
<label class=" control-label text-danger" >{{ error2 }}</label>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-info ">提交</button>
<button type="reset" class="btn btn-warning ">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="/static/js/jquery-1.11.1.min.js"></script>
<script>
$(function () {
$(':reset').click(function () {
$('.text-danger').hide()
})
})
</script>
</body>
</html>
改
# 更新编辑
def book_edit(request):
error, bn, bp = '', '', ''
pk = request.GET.get('pk')
ret = models.Book.objects.filter(pk=pk).first()
all_publish = models.Publish.objects.all().order_by('pk')
if not ret:
return HttpResponse('编辑内容不存在')
if request.method == 'POST':
bn = request.POST.get('bname')
bp = request.POST.get('bprice')
pub_sel = request.POST.get('pub-sel')
if not bn:
error = '内容不允许为空'
else:
# 更细字段的值
ret.bname = bn
ret.bprice = bp
########## 重点: pid_id是数据库中的字段,操作的是类的属性. 不对象类型的数据
ret.pid_id = pub_sel
########## 重点: pid 是类的属性,操作的另一个类实例的对象. 只能放对象类型数据
ret.pid=models.Book.objects.filter(pk=pub_sel).first()
# 保存
ret.save()
# 跳转
return redirect(to='/book_list/')
# 往前端页面传参
res = {'obj': ret, 'error': error, 'all_publish': all_publish, 'bn': bn, 'bp': bp}
return render(request, 'book_edit.html', res)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书管理系统</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/dashboard.css">
<link rel="icon" href="/static/imgs/user.png">
<style>
</style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="/index/">主页</a></li>
<li><a href="#">配置</a></li>
<li><a href="#">简介</a></li>
<li><a href="#">帮助</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="搜索...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li><a href="/publish_list/">出版社管理 </a></li>
<li><a href="/book_list/">图书管理</a></li>
</ul>
</div>
<div class="col-sm-8 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">图书更新</h2>
<div class="panel panel-success">
<div class="panel-heading ">图书更新</div>
<div class="panel-body">
<form class="form-horizontal" action="" method="post">
<div class="form-group">
<label for="bname" class="col-sm-2 control-label">图书名</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="bname" value="{{ obj.bname }}" name="bname"
placeholder="请填写图书名">
</div>
<label class=" control-label text-danger" id="error">{{ error }}</label>
</div>
<div class="form-group">
<label for="bprice" class="col-sm-2 control-label">图书价格</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="bprice" value="{{ obj.bprice }}"
name="bprice"
placeholder="请输入图书价格">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">图书的出版社</label>
<div class="col-sm-6">
<select name="pub-sel" id="" class="form-control">
<!-- 模版语言: if ... else ... endif的使用 -->
{% for publish in all_publish %}
{% if obj.pid_id == publish.pk %}
<option selected value="{{ publish.pk }}">{{ publish.pname }}</option>
{% else %}
<option value="{{ publish.pk }}">{{ publish.pname }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-info ">提交</button>
<button type="reset" class="btn btn-warning ">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="/static/js/jquery-1.11.1.min.js"></script>
<script>
$(function () {
$(':reset').click(function () {
$('#error').hide()
})
})
</script>
</body>
</html>
删
# 删除图书
def book_del(request):
pk=request.GET.get('pk')
ret=models.Book.objects.filter(pk=pk).first()
if not ret:
return HttpResponse('删除内容不存在哦!!!')
# 删除对象
ret.delete()
# 跳转到 查询页面
return redirect(to='/book_list')
项目地址:不告诉你哦~~~