阅读:63
做毕设前先练练手,使用django搭建一个简单的小说系统;(项目打包在结尾)
用户可以登录:
登录后可以浏览系统界面:
点击详情进入详情界面:点击收藏按钮,即可收藏小说。再次点击取消收藏。
用户主页展示已经收藏的小说条目:
model里有三个模型:用户模型,小说模型,收藏模型
其实就像课程关系、学生关系、选课关系一样。选课关系引入学生id、课程id作为外键,记录哪个学生选了哪些课。(为什么不直接用models.ManyToManyField,而要添加一个‘选课模型’呢?因为有数据库方面的好处,详见《数据库系统教程·第3版》)
# 用户模型
class User(models.Model):
username = models.CharField(max_length=50) # 用户账号
password = models.CharField(max_length=50) # 用户密码
def toDict(self):
return {'id': self.id, 'username': self.username, 'password': self.password}
class Meta:
db_table = "user" # 更改表名
# 小说模型
class Novel(models.Model):
title = models.CharField(max_length=60) # 小说标题
author = models.CharField(max_length=40) # 小说作者
def toDict(self):
return {'id': self.id, 'title': self.title, 'author': self.author}
class Meta:
db_table = "novel" # 更改表名
# 收藏模型,记录谁收藏,收藏了什么,收藏时间。
class CltNovel(models.Model):
who_clt = models.ForeignKey(to=User, on_delete=models.CASCADE) # 谁收藏
clt_relation_novel = models.ForeignKey(to=Novel, on_delete=models.CASCADE) # 收藏了哪篇小说
clt_time = models.DateTimeField(default=datetime.now) # 收藏时间
class Meta:
db_table = "cltnovel" # 更改表名
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.urls import reverse
from user.models import User, CltNovel
# 用户主页
def index(request):
"""用户主页"""
# 用户空间展示收藏夹
fmod = CltNovel.objects
uid = request.session['user']['id'] # 获取当前哪个用户登录
fav_list = fmod.filter(who_clt_id=uid) # 获取用户的所有收藏
context = {'favourite_list': fav_list}
return render(request, 'user/index.html', context)
# 用户登录表单
def login(request):
return render(request, 'user/login.html')
# 处理用户登录
def dologin(request):
try:
# 执行账号校验
user = User.objects.get(username=request.POST['usern'])
s = request.POST['passw']
# 检验成功
if s == user.password:
# 将当前登录成功的用户信息以user为key写入session中
request.session['user'] = user.toDict()
# 重定向到后台管理首页
return redirect(reverse('user_index'))
else:
# 登录失败
context = {'info': '密码错误!'}
except Exception as err:
print(err)
context = {'info': '账号不存在!'}
return render(request, 'user/login.html', context)
# 用户退出
def logout(request):
del request.session['user']
return redirect(reverse('user_login'))
# 删除收藏
def delete_fav(request):
fav_id = request.GET.get('id')
print(fav_id)
return HttpResponse(fav_id)
from django.shortcuts import render
from user.models import Novel, CltNovel
def index(request):
"""前台主页,展示所有的小说条目"""
nmod = Novel.objects # 实例化对象
list1 = nmod.all() # 展示所有小说条目
context = {'novellist': list1}
return render(request, 'web/index.html', context)
def detail(request):
"""跳转到详情界面"""
nid = request.GET.get('nid') # 接受到主页面要跳转到哪个小说的id
nmod = Novel.objects # 实例化对象
# 如果收藏夹里尚未有这个收藏:那个按钮应该是空心的。传送fav_status来表示收藏状态
uid = request.session['user']['id'] # session中提取当前登录的用户
fav_list = CltNovel.objects.filter(who_clt_id=uid) # 找出所有该用户的收藏
if fav_list.filter(clt_relation_novel_id=nid): # 检查有没有该小说id
fs = 1 # 已收藏
else:
fs = 0 # 未收藏
# todo filter和get的区别:filter筛选所有条件,queryset返回列表;get返回一个,有多个或没有找到会报错
n = nmod.get(id=nid)
context = {'novel_detail': n, 'fav_status': fs}
return render(request, 'web/detail.html', context)
from datetime import datetime
from django.http import HttpResponse
from user.models import CltNovel
# 收藏夹操作
def handle(request):
try:
sid = request.GET.get('id') # 前端获取被点击的小说id
uid = request.session['user']['id'] # session中提取是哪个用户要保存,即当前登录的用户
cltn = CltNovel()
# 如果收藏夹里尚未有这个收藏:那就收藏这个条目
# 如果收藏夹里已经有了,那就取消收藏
fav_list = CltNovel.objects.filter(who_clt_id=uid) # 找出所有该用户的收藏
if fav_list.filter(clt_relation_novel_id=sid): # 检查有没有该小说id
fav_list.filter(clt_relation_novel_id=sid).delete() # 收藏夹里已经有了,取消收藏
return HttpResponse('♡')
else:
cltn.who_clt_id = uid
cltn.clt_relation_novel_id = sid
cltn.clt_time = datetime.now()
cltn.save() # 收藏夹里尚未有这个收藏:收藏这个条目
return HttpResponse('♥')
except Exception as err:
print('失败,', err)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户主页</title>
<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
</head>
<body>
<h1>这是用户主页!</h1>
<div class="pull-right">
<a href="{% url 'user_logout' %}" class="btn btn-default btn-flat">退 出</a>
<p>我是:{{ request.session.user.username }}</p>
</div>
<div class="box-body table-responsive no-padding">
<table class="table table-hover">
<tr>
<th>收藏编号</th>
<th>小说编号</th>
<th>小说标题</th>
<th>小说作者</th>
</tr>
{% for vo in favourite_list %}
<tr>
<td>{{ vo.id }}</td>
<td>{{ vo.clt_relation_novel.id }}</td>
<td>{{ vo.clt_relation_novel.title }}</td>
<td>{{ vo.clt_relation_novel.author }}</td>
</tr>
{% endfor %}
</table>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录表单</title>
</head>
<body>
<h1>这是用户登录表单!</h1>
<p class="login-box-msg" style="color:red">{{ info }}</p>
<form action="{% url 'user_dologin' %}" method="post">
{% csrf_token %}
<input type="text" name="usern" class="form-control" placeholder="账号">
<input type="password" name="passw" class="form-control" placeholder="密码">
<button type="submit" class="btn btn-primary btn-block btn-flat">登录</button>
</form>
</body>
</html>
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小说系统首页</title>
<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
<script>
function clickMe() {
}
</script>
</head>
<body>
<h1>这是小说系统的首页!</h1>
<div class="box-body table-responsive no-padding">
<table class="table table-hover">
<tr>
<th>ID</th>
<th>小说名称</th>
<th>小说作者</th>
<th>操作</th>
</tr>
{% for vo in novellist %}
<tr>
<td>{{ vo.id }}</td>
<td>{{ vo.title }}</td>
<td>{{ vo.author }}</td>
<td>
<a href="{% url 'web_detail' %}?nid={{ vo.id }}">详情</a>
</td>
</tr>
{% endfor %}
</table>
</div>
</body>
</html>
使用ajax,点击一下就发送该小说id给views,表示要对这个小说收藏或取消收藏;
经过后端处理后,给收藏按变色。♥代表已收藏,♡代表未收藏。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小说详情</title>
<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
<script>
function clickSaveFav(){
// 发送异步ajax请求,发送get
$.ajax({
type: "get",
url: "{% url 'web_favourite_handle' %}",
data: "id={{ novel_detail.id }}",
success: function (response) {
let bt = document.getElementById("save_favourite")
bt.innerHTML = response
}
})
}
</script>
</head>
<body>
<h1>这是小说详情界面</h1>
<p>编号: {{ novel_detail.id }}</p>
<p>标题: {{ novel_detail.title }}</p>
<p>作者: {{ novel_detail.author }}</p>
<p>操作: <button id="save_favourite" onclick="clickSaveFav()">
{% if fav_status %}
♥
{% else %}
♡
{% endif %}
</button></p>
</body>
</html>
源码在这里:
链接:https://pan.baidu.com/s/1-25gju_JpDwJaF0ql_By1A?pwd=augj
提取码:augj
有用请赞