Django框架10 /sweetalert插件、中间件、多表图书系统总结

Django框架10 /sweetalert插件、中间件、多表图书系统总结

1.SweetAlert插件示例

1.https://github.com/lipis/bootstrap-sweetalert
  在github下载css、js文件放到项目静态文件夹中
2.在html页面分别引入jquery、bootstrap文件,sweetalert是基于bootstrap实现
3.将代码复制到script标签中

SweetAlert代码

$(".btn-danger").on("click", function () {
  swal({
    title: "你确定要删除吗?",
    text: "删除可就找不回来了哦!",
    type: "warning",
    showCancelButton: true,
    confirmButtonClass: "btn-danger",
    confirmButtonText: "删除",
    cancelButtonText: "取消",
    closeOnConfirm: false
    },
    function () {
      var deleteId = $(this).parent().parent().attr("data_id");
      // 注意:此处$(this)已经不是".btn-danger"这个点击的对象
      $.ajax({
        url: "/delete_book/",
        type: "post",
        data: {"id": deleteId},
        success: function (data) {
          if (data.status === 1) {
            swal("删除成功!", "你可以准备跑路了!", "success");
          } else {
            swal("删除失败", "你可以再尝试一下!", "error")
          }
        }
      })
    });
})

img

2.事务和锁

2.1 mysql

锁:
    select * from book where id=1 for update;
事务:
    begin
        select * from book where id=1 for update;
    commit  

2.2 django orm

models.Book.objects.select_for_update().filter(id=1)

事务

1.全局开启事务

1.在Web应用中,常用的事务处理方式是将每个请求都包裹在一个事务中。这个功能使用起来非常简单,你只需要将它的配置项ATOMIC_REQUESTS设置为True。

2.当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求却正确处理并正确返回了结果,Django就会提交该事务。否则,Django会回滚该事务。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mxshop',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': '123',
        'OPTIONS': {
            "init_command": "SET default_storage_engine='INNODB'",
       #'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", #配置开启严格sql模式


        }
        "ATOMIC_REQUESTS": True, #全局开启事务,绑定的是http请求响应整个过程
        "AUTOCOMMIT":False, #全局取消自动提交,慎用
    },
  'other':{
    'ENGINE': 'django.db.backends.mysql', 
            ......
  } #还可以配置其他数据库
}

2.局部使用事务

用法1:给函数做装饰器来使用

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()

用法2:作为上下文管理来使用,其实就是设置事务的保存点

from django.db import transaction

def viewfunc(request):
    # This code executes in autocommit mode (Django's default).
    do_stuff()

    with transaction.atomic():   #保存点
        # This code executes inside a transaction.
        do_more_stuff()

    do_other_stuff()

3. 中间件

3.1 中间件介绍

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

django默认自带的一些中间件:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

#MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。

3.2 自定义中间件

中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

# 注意:注意将自定义中间件添加到setting文件中注意顺序

process_request

process_request有一个参数,就是request,这个request和视图函数中的request是一样的。

# process_request方法里面不写返回值,默认也是返回None,如果你自己写了return None,也是一样的效果,不会中断你的请求,但是如果你return 的一个httpresponse对象,那么就会在这个方法中断你的请求,直接返回给用户,这就成了非正常的流程了
# 并且,如果你在这里return了httpresponse对象,那么会从你这个中间件类中的process_response方法开始执行返回操作,所以这个类里面只要有process_response方法,肯定会执行
from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("MD1里面的 process_request")

class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass
# settings.py的MIDDLEWARE配置项
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'middlewares.MD1',  # 自定义中间件MD1,这个写的是你项目路径下的一个路径,
    # 例如,如果你放在项目下,文件夹名成为utils,那么这里应该写utils.middlewares.MD1
    'middlewares.MD2'  # 自定义中间件MD2
]
MD1里面的 process_request
MD2里面的 process_request
app01 中的 index视图

process_response

1.它有两个参数,一个是request,一个是response,request就是上述例子中一样的对象,response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象
2.注意:process_response函数要有return response返回值
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Md1(MiddlewareMixin):
    def process_request(self,request):
        print("Md1请求")
 
    def process_response(self,request,response):
        print("Md1返回")
        return response

class Md2(MiddlewareMixin):
    def process_request(self,request):
        print("Md2请求")
        #return HttpResponse("Md2中断")
    def process_response(self,request,response):
        print("Md2返回")
        return response  ****
Md1请求
Md2请求
view函数...
Md2返回
Md1返回

cookie认证/中间件版

class M1(MiddlewareMixin):
    def process_request(self,request):
        #设置路径白名单,只要访问的是login登陆路径,就不做这个cookie认证
        if request.path not in [reverse('login'),]:
            print('我是M1中间件') 
            is_login = request.COOKIES.get('is_login', False)
            if is_login:
                pass
            else:
                # return render(request,'login.html')
                return redirect(reverse('login'))
        else:
            return None #别忘了return None,或者直接写个pass

    def process_response(self,request,response):
        print('M1响应部分')
        return response

process_view

process_view(self, request, view_func, view_args, view_kwargs)
在执行完url控制器后执行

四个参数:
request是HttpRequest对象。
1.view_func是Django即将使用的视图函数/它是实际的函数对象,而不是函数的名称作为字符串。
2.view_args是将传递给视图的位置参数的列表.
3.view_kwargs是将传递给视图的关键字参数的字典/view_args和view_kwargs都不包含第一个视图参数(request)。

Django会在调用视图函数之前调用process_view方法。

它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用对应的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("MD1里面的 process_request")
    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD1 中的process_view")
        print(view_func, view_func.__name__) #就是url映射到的那个视图函数,也就是说每个中间件的这个process_view已经提前拿到了要执行的那个视图函数
        #ret = view_func(request) #提前执行视图函数,不用到了上图的试图函数的位置再执行,如果你视图函数有参数的话,可以这么写 view_func(request,view_args,view_kwargs) 
        #return ret  #直接就在MD1中间件这里这个类的process_response给返回了,就不会去找到视图函数里面的这个函数去执行了。

class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD2 中的process_view")
        print(view_func, view_func.__name__)
MD2里面的 process_request
MD1里面的 process_request
-------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001DE68317488> index
-------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001DE68317488> index
app01 中的 index视图
MD1里面的 process_response
MD2里面的 process_response

process_exception

process_exception(self, request, exception)

两个参数:
1.一个HttpRequest对象
2.一个exception是视图函数异常产生的Exception对象。

这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

def index(request):
    print("app01 中的 index视图")
    raise ValueError("呵呵")
    return HttpResponse("O98K")
from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD1 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD1 中的process_exception")


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD2 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD2 中的process_exception")
MD1里面的 process_request
MD2里面的 process_request
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x0000022C09727488> index
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x0000022C09727488> index
app01 中的 index视图
呵呵
MD2 中的process_exception
MD2里面的 process_response
MD1里面的 process_response


#注意,这里并没有执行MD2的process_exception方法,因为MD1中的process_exception方法直接返回了一个响应对象。

process_template_response

process_template_response(self, request, response)

参数:
1.一个HttpRequest对象
2.response是TemplateResponse对象(由视图函数或者中间件产生)。

process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。
def index(request):
    print("app01 中的 index视图")
  #raise ValueError('出错啦') 
    def render():
        print("in index/render")  
        #raise ValueError('出错啦') #至于render函数中报错了,那么会先执行process_template_response方法,然后执行process_exception方法,如果是在render方法外面报错了,那么就不会执行这个process_template_response方法了。
        return HttpResponse("O98K") #返回的将是这个新的对象
        #raise ValueError('出错啦') 将报错放到这个位置不会报错
    rep = HttpResponse("OK")
    rep.render = render
    return rep

3.3 登陆认证之中间件

view.py

from django.shortcuts import render,HttpResponse,redirect

def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        name = request.POST.get('name')
        password = request.POST.get('password')
        if name == 'liu' and password == '123':
            request.session['is_login'] = True
            return redirect('index')
        else:
            return redirect('login')

def index(request):
    return render(request,'index.html')

mymiddleware.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,render,redirect

class MD1(MiddlewareMixin):
    white_list = ['/login/']
    def process_request(self,request):
        print('请求来了')
        path = request.path
        if  path not in self.white_list:
            status = request.session.get('is_login')
            if not status:
                return redirect('login')

    def process_response(self,request,response):
        print('响应走了')
        return response

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录页面</h1>
<form action="" method="post">
    {% csrf_token %}
用户名:<input type="text" name="name">     <!--input标签记得写name-->
密码:<input type="text" name="password">
<button class="submit">提交</button>
</form>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script></script>
</html>

4.多表图书管理系统总结

1.静态文件引入

{% load static %}   <!--static是关键字不能修改-->

<script src="{% static 'js/jquery.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'sw/sweetalert.min.js' %}"></script>

2.查看一本书的全部作者信息的高阶写法

原写法

show_book.html

<td>
    {% for author_obj in book_obj.authors.all %}
        {{ author_obj.name }}
        {% if forloop.last %}
    
        {% else %}
        ,
        {% endif %}
        {% endfor %}
</td>

初步高阶

models.py

class Book(models.Model):
    """
    书籍表
    """
    ...
    def get_authors_name(self):

        authors = self.authors.all()
        name_list = []
        for i in authors:
            name_list.append(i.name)
       
        return ','.join(name_list)

show_book.html

{{ book_obj.get_authors_name }}

高阶

models.py

class Book(models.Model):
    """
    书籍表
    """
    ...
    return ','.join(name_list)

show_book.html

{{ book_obj.get_authors_name }}

3.前端给后端传数据的第二种方式

<a href="{% url 'delbook' %}?book_id={{ book_obj.pk }}" class="btn btn-danger">删除</a>
def delbook(request):
    book_id = request.GET.get('book_id')
    models.Book.objects.filter(pk=book_id).delete()
    return redirect('showbooks')

4.删除书籍 ---ajax版

<script>
$('.delete').on('click',function(){
    var th = $(this);
    var book_id = $(this).attr('book_id');
    console.log(book_id);
        $.ajax({
        url:{% url 'remove_book' %},
        type:'post',
        data:{book_id:book_id,csrfmiddlewaretoken: "{{ csrf_token }}"},
        success:function(res){
            if (res.status === 1){
                th.parent().parent().remove();
            }
        }
})})
</script>
def remove_book(request):
    book_id = request.POST.get('book_id')
    print(book_id)
    book_obj = models.Book.objects.get(id=book_id)
    book_obj.delete()
    data = {"status":1}
    return JsonResponse(data)

猜你喜欢

转载自www.cnblogs.com/liubing8/p/11657238.html