python_day21_Django-5 (ajax,auth模块)

1、AJAX简介

  AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
  AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
  AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

AJAX在与后端交互的时候一定使用的是字典格式

ajax交互请求

  AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

优点

AJAX使用JavaScript技术向服务器发送异步请求;
AJAX请求无须刷新整个页面;
因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;

示例

方法一

html页面
<input type="text" id="a1">+
<input type="text" id="a2">=
<input type="text" id="a3">
<input type="button" id="b1" value="ajax提交">

<script src="/static/jQuery_3.3.1.js"></script>
<script>
    $("#b1").on("click", function () {
        $.ajax({
            url: "/edit/",
            type: "get",
            data:{a1:$("#a1").val(),a2:$("#a2").val()},
            success:function (arg) {
                $("#a3").val(arg);
            }
        })
    })
</script>

app下的views.py
from django.shortcuts import render, HttpResponse

# Create your views here.
def index(request):
    return render(request, "index.html")

def edit(request):
    print(request.GET)
    a1 = request.GET.get("a1")
    a2 = request.GET.get("a2")
    a3 = int(a1) + int(a2)
    return HttpResponse(a3)

项目下的urls.py
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("index/",views.index),
    path("edit/",views.edit),
]

局部刷新页面,赋值结果
python_day21_Django-5 (ajax,auth模块)

方法二:AJAX请求如何设置csrf_token

1、先获取csrf_name
    html页面中增加: {% csrf_token %}
    浏览器中获取: <input type="hidden" name="csrfmiddlewaretoken" value="9nahRbz6LB1KY6XFCqJSZvsck20FPHvNxQQpipc8ygJ62ZzFAD7EXU326MyowUQA">

2、javascript中携带csrf值   方法一  其它设置都一样
<script src="/static/jQuery_3.3.1.js"></script>
<script>
    $("#b1").on("click", function () {
        $.ajax({
            url: "/edit/",
            type: "get",
            data:{a1:$("#a1").val(),a2:$("#a2").val(),"csrfmiddlewaretoken":$("[name=csrfmiddlewaretoken]").val()},
            success:function (arg) {
                $("#a3").val(arg);
            }
        })
    })
</script>

3、方法二, 使用getcookie方法  
 定义一个js文件
// using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

然后在html文件中直接引用, 就能实现跟方法一,一样的效果了
<script src="/static/jQuery_3.3.1.js"></script>
<script src="/static/setupCsrf.js"></script>
<script>
    $("#b1").on("click", function () {
        $.ajax({
            url: "/edit/",
            type: "get",
            data:{a1:$("#a1").val(),a2:$("#a2").val()},
            success:function (arg) {
                $("#a3").val(arg);
            }
        })
    })
</script>

来自官网示例: https://docs.djangoproject.com/en/1.11/ref/csrf/

sweetalert

下载:https://github.com/lipis/bootstrap-sweetalert
使用说明: https://lipis.github.io/bootstrap-sweetalert/

实例

项目下的urls.py
from app01 import views
urlpatterns = [
    path("books/",views.books),
    path("delete/",views.delete),
]

应用下的view.py
from app01 import models
def books(request):
    ret = models.Books.objects.all()
    return render(request, "books.html", {"ret":ret})

def delete(request):
    delId = request.GET.get("id")
    models.Books.objects.filter(id=delId).delete()
    return HttpResponse("")

应用下的models.py   数据库表字段
from django.db import models

# Create your models here.

class Books(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=25)
    date = models.DateField(auto_now_add=True)

html页面
<head>
    <meta charset="UTF-8">
    <title>books</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.css">
    <link rel="stylesheet" href="/static/sweetalert/sweetalert.css">
    <style>
        .sweet-alert h2 {
            padding-top: 15px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">书本页面</h3>
        </div>
        <div class="panel-body">
            <table class="table table-striped">
                <thead>
                <tr>
                    <th>#</th>
                    <th>ID</th>
                    <th>书名</th>
                    <th>时间</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {% for foo in ret %}
                    <tr>
                        <td>{{ forloop.counter }}</td>
                        <td>{{ foo.id }}</td>
                        <td>{{ foo.name }}</td>
                        <td>{{ foo.date|date:'Y-m-d' }}</td>
                        <td>
                            <button class="btn btn-success del"><i class="fa fa-trash-o">删除</i></button>
                        </td>
                    </tr>
                {% endfor %}

                </tbody>
            </table>

        </div>
    </div>
</div>

<script src="/static/jQuery_3.3.1.js"></script>
<script src="/static/sweetalert/sweetalert.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
    $(".del").on("click", function () {
        $thisParn =  $(this).parent().parent()
        {# 点击事件的父级的父级 等于1的子级 id的文本内容 #}
        delID = $thisParn.children().eq(1).text()
        swal({
                title: "删除这行?",
                text: "确认删除?!",
                type: "warning",
                showCancelButton: true,
                confirmButtonClass: "btn-danger",
                confirmButtonText: "确认!",
                cancelButtonText: "取消",
                closeOnConfirm: false
            },
            function () {
                $.ajax({
                    url: '/delete/',
                    type: 'GET',
                    data: {id:delID},
                    success:function () {
            # 删除返回到数据库的ID这行,如果不删除那么只能刷新页面
                        $thisParn.remove();
                        swal("删除成功 !", "点击确认返回.", "success");
                    }
                });
            });

    })
</script>

最终效果
python_day21_Django-5 (ajax,auth模块)


2、AUTH模块

Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据

2.1、不使用auth模块

1、urls.py
urlpatterns = [
    // 登陆跟主页
    path("user_login/", views.userlogin),
    path("user_index/", views.userindex),
        // 注销
    path("cancellation/", views.cancellation),
]

2、html页面
index.html
<h1>index登陆主页</h1>

<p>欢迎 {{ userid.username }}</p>
<a href="/cancellation/">注销</a>

login.html页面
<h3>用户登陆界面</h3>
<form action="/user_login/" method="post">
    {% csrf_token %}
    <div>
        用户名: <input type="text" name="username">
    </div>

    <div>
        密码: <input type="password" name="passwd">
    </div>

    <input type="submit" value="登陆">

</form>

3、view.py
# 装饰器,用于检查用户是否登陆
def check_login(f):
    @wraps(f)
    def inner(request, *args, **kwargs):
        # 如果有session并且登陆成功赋值为1的,就直接返回, 否则就返回主页
        if request.session.get("is_login") == "1":
            return f(request, *args, **kwargs)
        else:
            return redirect("/user_login/")
    return inner

# 用户登陆函数, 获取from检查用户
def userlogin(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")

        ret = models.Login.objects.filter(username=username, passwd=passwd)
        if ret:
            request.session["is_login"] = "1"
            request.session["user_id"] = ret[0].id
            return redirect("/user_index/")
    return render(request, "author1/login.html")

# 装饰用户是否已经登陆,如果没有就返回主页并再次登陆
@check_login
def userindex(request):
    user_id = request.session.get("user_id")
    user_obj = models.Login.objects.filter(id=user_id)
    return render(request, "author1/index.html",{"userid":user_obj[0]})

# 清空session,注销该用户
def cancellation(request):
    request.session.flush()
    return redirect("/user_login/")

2.2、auth模块

导入auth模块 from django.contrib import auth
使用的时候需要先创建一个用户 python3 manage.py createsuperuser

2.2.1、authenticate()

提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username、password两个关键字参数、如果认证成功(用户名和密码正确有效),便会返回一个 User 对象
authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

urls.py跟html页面使用上面的
def userlogin(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        ret = auth.authenticate(username=username, password=passwd)
        if ret:
            return redirect("/user_index/")
    return render(request, "author1/login.html")

2.2.2、login(HttpRequest, user)  

该函数接受一个HttpRequest对象,以及一个经过认证的User对象。
该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据,类似于中件间的效果

from django.contrib import auth

def userlogin(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("passwd")
        ret = auth.authenticate(username=username, password=passwd)
        if ret:
                    # 在登陆之后封装了这个用户在后面的函数就可以直接调用request.user
            auth.login(request, ret)
            return redirect("/user_index/")
    return render(request, "author1/login.html")

def userindex(request):
    username = request.user.username
    print(username)
    return render(request, "author1/index.html")

控制台打印的就是登陆的用户名了

2.2.3、logout(request)

类似于不使用auth模块的 cancellation 注销函数,也是 清空了session
该函数接受一个HttpRequest对象,无返回值。
当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

def cancellation(request):
    auth.logout(request)
    return redirect("/user_login/")     # 跳转注销之后就返回到登陆页

2.2.4、login_requierd()

类似于不使用auth的装饰器模块
导入模块 from django.contrib.auth.decorators import login_required

@login_required
def userindex(request):
    username = request.user.username
    print(username)
    return render(request, "author1/index.html", {"user":request.user})    # 将数据发到前端

index页面
<p>欢迎 {{ user.username }}</p>

当用户没有登陆的时候会自动跳到主页 http://127.0.0.1:8000/user_login/?next=/user_index/

使用系统自带的装饰器,若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/, 如果需要自定义login页面,需要在settings.py中增加
LOGIN_URL = "/user_login/"

python_day21_Django-5 (ajax,auth模块)

2.2.5、创建用户\修改密码

导入模块 from django.contrib.auth.models import User

1、create_user()    # 创建普通用户
    urls中增加 path("user_register/", views.userreg),

def userreg(request):
    user = User.objects.create_user(username="xiong2", password="xiong123")
    return HttpResponse("创建成功")

python_day21_Django-5 (ajax,auth模块)


2、create_superuser()    # 创建超级用户 与普通用户一致

3、check_password(password)  # 检查密码
        def userreg(request):
                user = User.objects.get(username="xiong2")     # 获取到xiong2这个用户
                ret = user.check_password("123")                  # 检查密码是否是123
                print(ret)       #   结果false或者true

                return HttpResponse("创建成功")

4、set_password(password)
        def userreg(request):
                user = User.objects.get(username="xiong2")   # 获取用户
                user.set_password("123321")       #修改密码
                user.save()   # 一定要保存密码
                return HttpResponse("修改成功")  # 返回结果

python_day21_Django-5 (ajax,auth模块)
python_day21_Django-5 (ajax,auth模块)

2.3、扩展默认的auth_user表

models.py
class UserInfo(models.Model):
    phone = models.CharField(max_length=12)
    user = models.OneToOneField(to=User,on_delete=models.CASCADE)

相当于是做是一个外键关连表

1、models.py
# Create your models here.
class UserInfo(AbstractUser):
    """
    用户扩展表
    """
    phone = models.CharField(max_length=11, null=True)   # 允许为空
    addr = models.CharField(max_length=200, null=True)

    def __str__(self):
        return self.phone

# 引用Django自带的User表,继承使用时需要设置
AUTH_USER_MODEL = "app名.UserInfo"
比如我的应用名是 app01  models的类名 UserInfo
就需要在 settings.py 文件中加这一行  AUTH_USER_MODEL = 'app01.UserInfo'

python_day21_Django-5 (ajax,auth模块)

数据库中的user表就直接变成了 app01_userinfo表了
python_day21_Django-5 (ajax,auth模块)

转载于:https://blog.51cto.com/xiong51/2154366

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值