事务
事务:四大特性
-原子性
-一致性
-持久性
-隔离性
# 点赞点踩案例
1 点赞点踩增加记录
2 文章表中数字+1
# django中使用事务
1 导入
from django.db import transaction
2 使用上下文管理器使用
with transaction.atomic():
写的代码,会要么都成功
要么都失败
评论render显示
https://www.cnblogs.com/lisixian/
#1 前端使用bootstrap的列表组
前端
<div> <span id="id_commit_text">评论列表 </span> </div> <ul class="list-group"> {% for commit in commit_list %} <li class="list-group-item"> <div> <span><a href=""># {{ forloop.counter }} 楼</a></span> <span>{{ commit.create_time|date:"Y-m-d H:i" }}</span> <span><a href="/{{ commit.user.username }}">{{ commit.user.username }}</a></span> </div> <div style="padding: 10px"> {# 判断 parent_id是否为空,如果为空,就是下面,如果不为空,找到父评论人名 @#} {% if commit.parent_id %} <a href="/{{ commit.parent_id.user.username }}">@ {{ commit.parent_id.user.username }}</a> {% endif %} <br> {{ commit.content }} </div> </li> {% endfor %} </ul> </div>
后端
def article_detail(request, username, article_id): article = Article.objects.filter(pk=article_id).first() commit_list=Commit.objects.filter(article_id=article.id) return render(request, 'article_detail.html', locals())
根评论提交和ajax的显示
前端提交
$("#btn_commit").click(function () { // 谁给哪篇文章 评论了什么内容---》必须登录 var content = $("#id_text").val() if (content) { $.ajax({ url: '/commit/', method: 'post', data: { article_id: '{{ article.id }}', content: content, csrfmiddlewaretoken: '{{ csrf_token }}' }, success: function (data) { console.log(data) if (data.code == 100) { // 把 字符串标签,拼接在后面 es6 模板字符串语法--》类似于python的 'asdfas%sasdf%d' var html_content = ` <li class="list-group-item"> <p><span class="fa fa-address-card-o">${data.username}:</span></p> <p>${data.content}</p> </ul> ` $('.list-group').append(html_content) } } }) } else { $('#alert_error').removeClass('hidden') } })
后端接口
def commit(request): user = request.user if user.is_authenticated: article_id = request.POST.get('article_id') content = request.POST.get('content') with transaction.atomic(): commit = Commit.objects.create(user=user, article_id=article_id, content=content) # 评论数 +1 Article.objects.filter(pk=article_id).update(commit_number=F('commit_number') + 1) return JsonResponse({'code': '100', 'msg': '评论成功', 'content': commit.content,'username':user.username}) else: return JsonResponse({'code': '101', 'msg': '没有登录'})
子评论提交--ajax显示
前端
## html中: <div class="pull-right"> <span style="margin-left: 10px;margin-right: 10px" class="replay" username="{{ commit.user.username }}" commit_id="{{ commit.id }}"><a>回复</a></span> <span>删除</span> </div> ## js中:给回复绑定事件 var parent_id=null $('.replay').click(function () { var username = "@" + $(this).attr('username') + '\n' $("#id_text").val(username) parent_id = $(this).attr('commit_id') }) ## 评论提交 $("#btn_commit").click(function () { var content = $("#id_text").val() if (parent_id) { var i = content.indexOf('\n') // 找到 \n在字符串中得位置 4 content = content.substring(i + 1) // 把字符串截断,只要 \n往后额 console.log(content); } if (content) { $.ajax({ url: '/commit/', method: 'post', data: { parent_id: parent_id, article_id: '{{ article.id }}', content: content, csrfmiddlewaretoken: '{{ csrf_token }}' }, success: function (data) { console.log(data) if (data.code == 100) { $("#id_text").val('') // 清空输入框内容 var html_content = ` <li class="list-group-item"> <p><span class="fa fa-address-card-o">${data.username}:</span></p> <p>${data.content}</p> </ul> ` $('.list-group').append(html_content) } else if (data.code == 103) { $("#id_text").val('') // 清空输入框内容 var html_content = ` <li class="list-group-item"> <p><span class="fa fa-address-card-o">${data.username}:</span></p> <p>@${data.parent_name}</p> <p>${data.content}</p> </ul> ` $('.list-group').append(html_content) } } }) } else { $('#alert_error').removeClass('hidden') } })
后端
def commit(request): user = request.user if user.is_authenticated: article_id = request.POST.get('article_id') content = request.POST.get('content') parent_id = request.POST.get('parent_id') with transaction.atomic(): commit = Commit.objects.create(user=user, article_id=article_id, content=content, parent_id_id=parent_id) # 评论数 +1 Article.objects.filter(pk=article_id).update(commit_number=F('commit_number') + 1) if commit.parent_id: return JsonResponse({'code': '103', 'msg': '评论成功', 'content': commit.content, 'username': user.username, 'parent_name': commit.parent_id.user.username}) else: return JsonResponse( {'code': '100', 'msg': '评论成功', 'content': commit.content, 'username': user.username}) else: return JsonResponse({'code': '101', 'msg': '没有登录'})
后台管理页面
后端
@login_required(login_url='/login/') def backend(request): article_list = Article.objects.filter(blog=request.user.blog) return render(request, 'backend/backend_index.html', locals())
前端backend_base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>后台管理</title> <script src="/static/js/jquery.min.js"></script> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <script src="/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid navbar-inverse"> <div class="navbar-header "> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <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><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="row"> <div class="col-md-2"> <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="headingOne"> <h4 class="panel-title"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> 博客后台 </a> </h4> </div> <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <ul class="nav nav-pills nav-stacked nav-pills-stacked-example"> <li role="presentation"><a href="#">新建文章</a></li> <hr> <li role="presentation"><a href="#">修改头像</a></li> <hr> <li role="presentation"><a href="#">草稿箱</a></li> </ul> </div> </div> </div> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="headingTwo"> <h4 class="panel-title"> <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> 分类 </a> </h4> </div> <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo"> <div class="panel-body"> <ul class="nav nav-pills nav-stacked nav-pills-stacked-example"> <li role="presentation"><a href="#">分类一</a></li> <hr> <li role="presentation"><a href="#">分类二</a></li> </ul> </div> </div> </div> </div> </div> <div class="col-md-9"> <div class="bs-example bs-example-tabs" data-example-id="togglable-tabs"> <ul id="myTabs" class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"><a href="#home" id="home-tab" role="tab" data-toggle="tab" aria-controls="home" aria-expanded="true">文章</a></li> <li role="presentation" class=""><a href="#profile" role="tab" id="profile-tab" data-toggle="tab" aria-controls="profile" aria-expanded="false">随笔</a></li> <li role="presentation" class="dropdown"> <a href="#" id="myTabDrop1" class="dropdown-toggle" data-toggle="dropdown" aria-controls="myTabDrop1-contents" aria-expanded="false">更多 <span class="caret"></span></a> <ul class="dropdown-menu" aria-labelledby="myTabDrop1" id="myTabDrop1-contents"> <li><a href="#dropdown1" role="tab" id="dropdown1-tab" data-toggle="tab" aria-controls="dropdown1">相册</a></li> <li><a href="#dropdown2" role="tab" id="dropdown2-tab" data-toggle="tab" aria-controls="dropdown2">测试</a></li> </ul> </li> </ul> <div id="myTabContent" class="tab-content"> <div role="tabpanel" class="tab-pane fade active in" id="home" aria-labelledby="home-tab"> {% block articles %} {% endblock %} </div> <div role="tabpanel" class="tab-pane fade" id="profile" aria-labelledby="profile-tab"> 随笔 </div> <div role="tabpanel" class="tab-pane fade" id="dropdown1" aria-labelledby="dropdown1-tab"> 相册 </div> <div role="tabpanel" class="tab-pane fade" id="dropdown2" aria-labelledby="dropdown2-tab"> 更多 </div> </div> </div> </div> </div> </div> </body> {% block script %} {% endblock %} </html>
backend_index.html
{% extends 'backend/backend_base.html' %} {% block articles %} <div> <table class="table table-striped"> <thead> <tr> <th>文章id</th> <th>文章名字</th> <th>创建时间</th> <th>操作</th> </tr> </thead> <tbody> {% for article in article_list %} <tr> <th scope="row">{{ article.id }}</th> <td><a href="/{{ request.user.username }}/articles/{{ article.id }}.html">{{ article.title }}</a> </td> <td>{{ article.create_time|date:"Y年m月d日" }}</td> <td><a href="">编辑</a> | <a href="/delete/{{ article.id }}">删除</a></td> </tr> {% endfor %} </tbody> </table> </div> {% endblock %}
删除文章功能
<a href="/delete/{{ article.id }}">删除</a> @login_required(login_url='/login/') def delete_article(request, pk): Article.objects.filter(pk=pk).delete() return redirect('/backend/')
新增文章功能
后台
@login_required(login_url='/login/') def add_article(request): if request.method == 'GET': # 当前作者所有分类 category_list = Category.objects.filter(blog=request.user.blog).all() tag_list = Tag.objects.filter(blog=request.user.blog).all() return render(request, 'backend/add_article.html', locals()) else: title = request.POST.get('title') content = request.POST.get('content') category = request.POST.get('category') desc = content[0:70] tag = request.POST.getlist('tag') article = Article.objects.create(title=title, desc=desc, content=content, category_id=category, blog=request.user.blog) # 中间表如果自动生成,有如下方式操作中间表 article.tag.add(*tag) # id 或对象 都可以 article.tag.add(1,2) # article.tag.clear() # article.tag.set() # article.tag.remove() return redirect('/backend/')
前台
{% extends 'backend/backend_base.html' %} {% block articles %} <div> <h3 class="text-center">添加文章</h3> <form method="post"> {% csrf_token %} <div class="form-group"> <label for="">标题</label> <input type="text" class="form-control" name="title"> </div> <div class="form-group"> <label for="">内容</label> <textarea name="content" id="" cols="200" rows="10" class="form-control"></textarea> </div> <div class="form-group"> <label for="">分类</label> <select class="form-control" name="category"> {% for category in category_list %} <option value="{{ category.id }}">{{ category.name }}</option> {% endfor %} </select> </div> <div class="form-group"> <label for="">标签</label> <select class="form-control" multiple name="tag"> {% for tag in tag_list %} <option value="{{ tag.id }}">{{ tag.name }}</option> {% endfor %} </select> </div> <div class="text-center"> <button class="btn btn-danger">新增文章</button> </div> </form> </div> {% endblock %}
标签:06,request,content,user,article,commit,BBS,id From: https://www.cnblogs.com/wzh366/p/17899227.html