django入门项目图书管理
该项目利用了django实现了对图书的增删改查操作
步骤
1.在setting下配置好静态文件路径
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static'),
]
2.models.py
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField(max_length=32, unique=True)
price = models.DecimalField(max_digits=8, decimal_places=2, null=True) # 999999.99
pub_date = models.DateTimeField()
publish = models.ForeignKey(to="Publish", to_field="id", on_delete=models.CASCADE)
authors = models.ManyToManyField(to="Author")
def __str__(self):
return self.title
class Publish(models.Model):
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
# ad=models.ForeignKey(to="AuthorDetail",to_field="id",on_delete=models.CASCADE,unique=True)
ad = models.OneToOneField(to="AuthorDetail", to_field="id", on_delete=models.CASCADE, )
def __str__(self):
return self.name
class AuthorDetail(models.Model):
gf = models.CharField(max_length=32)
tel = models.CharField(max_length=32)
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
last_time = models.DateTimeField()
3.终端面板执行数据库生成与迁移命令
python3 manage.py makemigrations python3 manage.py migrate
4.urls.py
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('books/', views.books, name='books'),
path('add_book/', views.add_book, name='add_book'),
# re_path('edit_book/(?P<id>\d+)/(?P<id2>\w+)', views.edit_book, name='edit_book'),
re_path('edit_book/(\d+)/', views.edit_book, name='edit_book'),
re_path('del_book/', views.del_book, name='del_book'),
re_path('login/', views.login, name='login'),
re_path('logout/', views.logout, name='logout'),
]
5.views.py
from django.shortcuts import render, HttpResponse, redirect, reverse
from app01 import models
import json
import datetime
# 装饰器,这个装饰器前提需要在inner中引入一个request形参,这里使用了args[0]来获取requset
# 对于这里,其实使用auth模块下的login_required来装饰更加方便
def required_login(func):
def inner(*args, **kwargs):
request= args[0]
# if request.COOKIES.get('is_login'):
if request.session.get('is_login'):
return func(*args, **kwargs)
else:
if request.is_ajax():
return HttpResponse(json.dumps({'status':0,'url':reverse('login')}))
return redirect(reverse('login'))
return inner
@required_login
def books(request):
books = models.Book.objects.all()
return render(request, 'books.html', {'books': books})
@required_login
def add_book(request):
if request.method == 'POST':
title = request.POST.get('name')
price = request.POST.get('price')
date = request.POST.get('date')
publish = request.POST.get('publish')
# 多个作者,使用getlist
authors = request.POST.getlist('authors')
new_book = models.Book.objects.create(title=title, price=price, pub_date=date, publish_id=publish)
new_book.authors.set(authors)
return redirect(reverse('books'))
# get请求,在前端添加默认信息
publishers = models.Publish.objects.all()
authors = models.Author.objects.all()
return render(request, 'add_book.html',locals())
# return render(request, 'add_book.html', {'publishers': publishers, 'authors': authors})
@required_login
def edit_book(request, edit_id):
book_obj = models.Book.objects.get(id=edit_id)
if request.method == 'POST':
title = request.POST.get('name')
price = request.POST.get('price')
date = request.POST.get('date')
publish = request.POST.get('publish')
authors = request.POST.getlist('authors')
book_obj.title = title
book_obj.price = price
book_obj.pub_date = date
book_obj.publish_id = publish
book_obj.save()
book_obj.authors.set(authors)
# 反向解析,重定向
return redirect(reverse('books'))
publishers = models.Publish.objects.all()
authors = models.Author.objects.all()
return render(request,'edit_book.html',locals())
# return render(request, 'edit_book.html', {'book_obj': book_obj, 'publishers': publishers, 'authors': authors})
@required_login
def del_book(request):
del_id = request.POST.get('del_id')
del_list = models.Book.objects.filter(id=del_id)
print(del_list)
# del_list.delete()
return HttpResponse(json.dumps({'status': 1}))
def login(request):
if request.method == 'POST':
name = request.POST.get('user')
pwd = request.POST.get('pwd')
user_list = models.User.objects.filter(name=name, pwd=pwd)
if user_list:
user_obj = user_list.first()
ret = redirect(reverse('books'))
# ret.set_cookie('is_login', True)
# ret.set_cookie('user', name)
# ret.set_cookie('last_time', user_obj.last_time)
request.session['is_login'] =True
request.session['user'] =name
request.session['last_time'] =str(user_obj.last_time)
user_obj.last_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(user_obj.last_time)
user_obj.save()
return ret
return render(request, 'login.html')
def logout(request):
ret = redirect(reverse('login'))
# ret.delete_cookie('is_login')
# ret.delete_cookie('user')
# ret.delete_cookie('last_time')
request.session.flush()
return ret
6.模板配置(注意static中文件的导入方式)
静态文件下载路径
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
<link rel="stylesheet" href="/static/css/login.css">
</head>
<body>
<div class="container">
<form class="form-signin" action="{% url 'login' %}" method="post">
{% csrf_token %}
<h2 class="form-signin-heading">请登陆</h2>
<label for="user" class="sr-only">Email address</label>
<input type="text" id="user" class="form-control" placeholder="用户名" required="" autofocus="" name="user">
<label for="inputPassword" class="sr-only">密码</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required="" name="pwd">
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> 记住我
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">登陆</button>
</form>
</div> <!-- /container -->
</body>
</html>
books.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
<link rel="stylesheet" href="/static/css/books.css">
<link rel="stylesheet" href="/static/plugins/sweetalert/sweetalert.css">
</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="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
{# <li><a href="#">{{ request.COOKIES.user }}</a></li>#}
{# <li><a href="#">{{ request.COOKIES.last_time }}</a></li>#}
<li><a href="#">{{ request.session.user }}</a></li>
<li><a href="#">{{ request.session.last_time }}</a></li>
<li><a href="{% url 'logout' %}">注销</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</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 class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<a href="{% url 'add_book' %}" class="btn btn-primary">添加</a>
<table class="table table-hover">
<thead>
<tr>
<th>序号</th>
<th>书名</th>
<th>价格</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<th scope="row">{{ forloop.counter }}</th>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>{{ book.pub_date |date:'Y-m-d' }}</td>
<td>{{ book.publish.name }}</td>
<td>
{#对多个作者进行效果处理#}
{% for author in book.authors.all %}
{% if forloop.last %}
{{ author.name }}
{% else %}
{{ author.name }} |
{% endif %}
{% endfor %}
</td>
<td>
<a href="{% url 'edit_book' book.id %}" class="btn btn-sm btn-warning">编辑</a>
<a edit_id="{{ book.id }}" class="btn btn-sm btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script src="/static/plugins/jquery-3.3.1.min.js"></script>
<script src="/static/plugins/sweetalert/sweetalert-dev.js"></script>
{% csrf_token %}
<script>
$(".btn-danger").click(function () {
_this = $(this)
swal({
title: "确定删除吗?",
text: "你将无法恢复该虚拟文件!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "确定删除!",
cancelButtonText: "取消删除!",
closeOnConfirm: false,
closeOnCancel: false
},
function (isConfirm) {
if (isConfirm) {
swal("删除!", "你的虚拟文件已经被删除。",
"success");
$.ajax({
url:{% url 'del_book' %},
type: 'post',
data: {
del_id: _this.attr('edit_id'),
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
var data = JSON.parse(data)
if (data.status) {
_this.parent().parent().remove()
}else {
window.location=data.url
}
}
})
} else {
swal("取消!", "你的虚拟文件是安全的:)",
"error");
}
});
})
</script>
</body>
</html>
add_book.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div class="container">
<form class="form-horizontal" action="{% url 'add_book' %}" method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-sm-2 control-label">书名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" placeholder="name" name="name">
</div>
</div>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">价格</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="price" placeholder="price" name="price">
</div>
</div>
<div class="form-group">
<label for="date" class="col-sm-2 control-label">出版日期</label>
<div class="col-sm-10">
<input type="date" class="form-control" id="date" name="date">
</div>
</div>
<div class="form-group">
<label for="publish" class="col-sm-2 control-label">出版社</label>
<div class="col-sm-10">
<select name="publish" id="publish" class="form-control">
{% for publisher in publishers %}
<option value="{{ publisher.id }}">{{ publisher.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="authors" class="col-sm-2 control-label">作者</label>
<div class="col-sm-10">
<select name="authors" id="authors" class="form-control" multiple>
{% for author in authors %}
<option value="{{ author.id }}">{{ author.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
</div>
</body>
</html>
edit_book.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div class="container">
<form class="form-horizontal" action="{% url 'edit_book' book_obj.id %}" method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-sm-2 control-label">书名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" placeholder="name" name="name"
value="{{ book_obj.title }}">
</div>
</div>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">价格</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="price" placeholder="price" name="price"
value="{{ book_obj.price }}">
</div>
</div>
<div class="form-group">
<label for="date" class="col-sm-2 control-label">出版日期</label>
<div class="col-sm-10">
<input type="date" class="form-control" id="date" name="date"
value="{{ book_obj.pub_date |date:'Y-m-d' }}">
</div>
</div>
<div class="form-group">
<label for="publish" class="col-sm-2 control-label">出版社</label>
<div class="col-sm-10">
<select name="publish" id="publish" class="form-control">
{% for publisher in publishers %}
{% if book_obj.publish == 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">
<label for="authors" class="col-sm-2 control-label">作者</label>
<div class="col-sm-10">
<select name="authors" id="authors" class="form-control" multiple>
{% for author in authors %}
{% if author in book_obj.authors.all %}
<option value="{{ author.id }}" selected>{{ author.name }}</option>
{% else %}
<option value="{{ author.id }}">{{ author.name }}</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-default">提交</button>
</div>
</div>
</form>
</div>
</body>
</html>
2.基于forms组件实现的增删改查

浙公网安备 33010602011771号