六、Django开发

六、Django开发

    • 1.新建项目
    • 2.创建app
      • 2.1 第一种方法:
      • 2.2 利用pycharm中tools工具直接创建app
    • 3.设计表结构(django)
    • 4.在MySQL中生成表
    • 5.静态文件管理
    • 6.部门管理
      • 6.1 部门列表
    • 7.模板的继承
    • 8.用户管理
      • 8.1初识Form
        • 1.views.py
        • 2.user_add.html
      • 8.2ModelForm(推荐)
        • 0.models.py
        • 1.views.py
        • 2.user_model_form_add.html
  • day17Django开发
      • 8.4 编辑用户
      • 8.5删除
    • 9.靓号管理
      • 9.1表结构
      • 9.2靓号列表
      • 9.3 新建靓号
      • 9.4编辑靓号
      • 9.5搜索手机号
      • 9.6分页
    • 10.时间插件
    • 11.ModelForm和BootStrap
      • 操作
    • 12.管理员操作
    • 13.用户登录
        • 13.1登录
        • 13.2中间件的体验
        • 13.3中间价实现登录校验
        • 13.4注销
        • 13.5当前用户
    • 14.图片验证码
      • 14.1生成图片
    • 15.Ajax请求
      • 15.1GET请求
      • 15.2POST请求
      • 15.3关闭绑定事件
      • 15.4ajax请求的返回值

主题:员工管理系统

1.新建项目

在这里插入图片描述

2.创建app

2.1 第一种方法:

直接在终端中输入命令:

python manage.py startapp app01

2.2 利用pycharm中tools工具直接创建app

在这里插入图片描述

注册app:

在这里插入图片描述

3.设计表结构(django)

在这里插入图片描述

from django.db import models


class Department(models.Model):
    """ 部门表 """
    title = models.CharField(max_length=32, verbose_name='标题')


class UserInfo(models.Model):
    """ 员工表 """
    name = models.CharField(max_length=16, verbose_name='姓名')
    password = models.CharField(max_length=64, verbose_name='密码')
    age = models.IntegerField(verbose_name='年龄')
    account = models.DecimalField(decimal_places=2, verbose_name='账户余额', max_digits=10, default=0)

    create_time = models.DateTimeField(verbose_name='入职时间')

    # 无约束
    # depart_id = models.BigIntegerField(verbose_name="部门ID")

    # 1、有约束
    #   -to, 与哪张表关联
    #   -to_field,表中的哪一列关联
    # 2、django自动
    #   - 写的depart
    #   - 生成数据列 depart_id
    # 3、部门表被删除
    # 3.1 级联删除
    depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
    # 3.2 置空
    # depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.SET_NULL(), verbose_name='部门ID', null=True, blank=True)

    # 在django中做约束
    gender_choices = (
        (1, "男"),
        (2, "女")
    )
    gender = models.SmallIntegerField(choices=gender_choices, verbose_name='性别')

4.在MySQL中生成表

  • 工具连接MySQL生成数据库。

    create database gx_day16 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
    
  • 修改配置文件,连接MySQL

    在这里插入图片描述

    DATABASES = {
        'default':
            {
                'ENGINE': 'django.db.backends.mysql',  # 数据库引擎
                'NAME': 'gx_day16',  # 数据库名称
                'HOST': '127.0.0.1',  # 数据库地址,本机 ip 地址 127.0.0.1
                'PORT': 3306,  # 端口
                'USER': 'root',  # 数据库用户名
                'PASSWORD': 'xxxx',  # 数据库密码
            }
    }
    
  • django命令生成数据库表

    第一种方式:在终端中输入

    python manage.py makemigrations
    python namage.py migrate
    

    第二种方式:在pycharm的tools工具中输入

    在这里插入图片描述

表结构创建成功:

在这里插入图片描述

5.静态文件管理

static目录

在这里插入图片描述

6.部门管理

体验,最原始方法来做。

Django中提供Form和ModelForm组件(方便)

6.1 部门列表

在这里插入图片描述

7.模板的继承

  • 部门列表
  • 添加部门
  • 编辑部门

定义模板:layout.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</head>
<body>
    <h1>标题</h1>
    <div>
        {% block content %}
        {% endblock %}
    </div>
    <h1>底部</h1>
    
	<script src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
    {% block js %}{% endblock %}
</body>
</html>

继承模板:

{% extends 'layout.html' %}

{% block css %}
    <link rel="stylesheet" href="{% static 'plugins/xxxxx' %}">
	<style>
		...
	</style>
{% endblock %}

{% block content %}
    <h1>首页</h1>
{% endblock %}

{% block js %}
    <link rel="stylesheet" href="{% static 'js/xxxxx' %}">
{% endblock %}

8.用户管理

insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("韩超","666",23,100.68,"2010-11-11",2,1);

insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("刘东","123",23,100.68,"2010-11-11",1,4);

insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("朱虎飞","999",23,9900.68,"2010-11-11",1,4);
+-------------+---------------+------+-----+---------+----------------+
| Field       | Type          | Null | Key | Default | Extra          |
+-------------+---------------+------+-----+---------+----------------+
| id          | bigint        | NO   | PRI | NULL    | auto_increment |
| name        | varchar(16)   | NO   |     | NULL    |                |
| password    | varchar(64)   | NO   |     | NULL    |                |
| age         | int           | NO   |     | NULL    |                |
| account     | decimal(10,2) | NO   |     | NULL    |                |
| create_time | datetime(6)   | NO   |     | NULL    |                |
| gender      | smallint      | NO   |     | NULL    |                |
| depart_id   | bigint        | NO   | MUL | NULL    |                |
+-------------+---------------+------+-----+---------+----------------+

在这里插入图片描述

新建用户:

  • 原始方式理思路:不会采用(本质)【麻烦】

    - 用户提交数据没有校验。
    - 错误,页面上应该有错误提示。
    - 页面上,每一个字段都需要我们重新写一遍。    [ok]
    - 关联的数据,手动去获取并展示循环展示在页面。 [ok]
    
  • Django组件

    • Form组件(小简便)
    • ModelForm(最简便)

8.1初识Form

1.views.py
class MyForm(From):
    user = forms.charField(widget=froms.Input)
    pwd = forms.charField(widget=froms.Input)
    email = forms.charField(widget=froms.Input)


def user_add(request):
    """ 添加用户 (原始方式)"""
    if request.method == 'GET':
        form = MyForm()
        return render(request, "user_add.html", {"form":form})
2.user_add.html
<form method="post">
    {% for field in form%}
    	{{ field }}
    {% endfor %}
	<!-- <input type="text" class="form-control" placeholder="姓名" name="user"> -->
</form>
<form method="post">
    {{ form.user }}
    {{ form.pwd }}
    {{ form.email }}
	<!-- <input type="text" class="form-control" placeholder="姓名" name="user"> -->
</form>

8.2ModelForm(推荐)

0.models.py
class UserInfo(models.Model):
    """ 员工表 """
    name = models.CharField(max_length=16, verbose_name='姓名')
    password = models.CharField(max_length=64, verbose_name='密码')
    age = models.IntegerField(verbose_name='年龄')
    account = models.DecimalField(decimal_places=2, verbose_name='账户余额', max_digits=10, default=0)

    create_time = models.DateTimeField(verbose_name='入职时间')

    depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
    
    gender_choices = (
        (1, "男"),
        (2, "女")
    )
    gender = models.SmallIntegerField(choices=gender_choices, verbose_name='性别')
1.views.py
class MyForm(From):
    xx = form.CharField("...")
    class Meta:
        model = UserInfo
        fields = ["name", "password", "age", "xx"]

def user_add(request):
    """ 添加用户 (原始方式)"""
    if request.method == 'GET':
        form = MyForm()
        return render(request, "user_add.html", {"form":form})
2.user_model_form_add.html
{% extends 'layout.html' %}

{% block content %}

     <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">新建用户</h3>
                </div>
                <div class="panel-body">
                    <form method="post" novalidate>
                        {% csrf_token %}

                        {% for field in form %}
                        <div class="form-group">
                            <label>{{ field.label }}</label>
                            {{ field }}
                            <span style="color: red">{{ field.errors.0 }}</span>
                        </div>
                        {% endfor %}

                        <button type="submit" class="btn btn-primary">提 交</button>
                    </form>
                </div>
            </div>
        </div>

{% endblock %}

<form method="post">
    {% csrf_token %}
    {% for field in form %}
        {{ field.label }}: {{ field }}
    {% endfor %}
</form>
</body>
</html>

day17Django开发

  • 部门管理

  • 用户管理

    • 用户列表

    • 新建用户

      - ModelForm,针对数据库中的某个表。
      - Form。
      

8.4 编辑用户

  • 点击编辑,跳转到编辑页面(将编辑行的ID携带过去)。

  • 编辑页面(默认数据,根据ID获取并设置到页面中)

  • 提交:

    • 错误提示

    • 数据校验

    • 在数据库更新

      models.UserInfo.filter(id=4).update(...)
      
def user_edit(request, nid):
    """ 编辑用户信息 """
    row_object = models.UserInfo.objects.filter(id=nid).first()

    if request.method == 'GET':
        # 根据ID去数据库获取要编辑的那一行数据(对象)
        form = UserModelForm(instance=row_object)
        return render(request, 'user_edit.html', {'form': form})

    form = UserModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        # 默认保存的是用户输入的所有数据,如果想要再用户输入以外增加一些值
        # form.instance.字段名 = 值
        form.save()
        return redirect('/user/list/')
    return render(request, 'user_edit.html', {'form': form})

8.5删除

def user_delete(request, nid):
    """ 删除用户信息 """
    models.UserInfo.objects.get(id=nid).delete()

    return redirect('/user/list/')

9.靓号管理

9.1表结构

在这里插入图片描述

根据表结构的需求,在models.py中创建类(有类生成数据库中的表)。

class PrettyNum(models.Model):
    """ 靓号表 """
    mobile = models.CharField(max_length=11, verbose_name='手机号')
    # 想要允许为空 null=True, blank=True
    price = models.IntegerField(verbose_name='价格', default=0)

    level_choice = (
        (1, '1级'),
        (2, '2级'),
        (3, '3级'),
        (4, '4级'),
    )
    level = models.SmallIntegerField(choices=level_choice, verbose_name='级别', default=1)

    status_choice = (
        (1, '已占用'),
        (2, '未占用')
    )
    status = models.SmallIntegerField(choices=status_choice, verbose_name='状态', default=2)

自己在数据模拟创建一些数据:

insert into app01_prettynum(mobile,price,level,status) values("1111111",19,1,1);
mysql> select * from app01_prettynum;
+----+---------+-------+-------+--------+
| id | mobile  | price | level | status |
+----+---------+-------+-------+--------+
|  1 | 1111111 |    19 |     1 |      1 |
|  2 | 1111111 |    19 |     1 |      1 |
|  3 | 1111111 |    19 |     1 |      1 |
|  4 | 1111111 |    19 |     1 |      1 |
+----+---------+-------+-------+--------+
4 rows in set (0.00 sec)

9.2靓号列表

  • url

  • 函数

    • 获取所欲的靓号

    • 结合html+render将靓号罗列出来

      id 号码 价格 级别(中文) 状态(中文)
      

9.3 新建靓号

  • 列表点击跳转:/pretty/add/

  • url

  • ModelForm类

    from django import forms
    
    class PrettyModelForm(forms.ModelForm):
    	...
    
  • 函数

    • 实例化类的对象
    • 通过render将对象传入到HTML中
    • 模板的循环展示所有的字段
  • 点击提交

    • 数据校验
    • 保存到数据库
    • 跳转回靓号列表

    在这里插入图片描述

9.4编辑靓号

  • 列表页面:/pretty/数字/edit/
  • url
  • 函数
    • 根据ID获取当前编辑的对象
    • ModelForm配合,默认显示数据
    • 提交修改

在这里插入图片描述

不允许手机号重复。

  • 添加:【正则表达式】 【手机号不能存在】

    # [obj,obj,obj]
    queryset = models.PrettyNum.objects.filter(mobile="188888888")
    
    obj = models.PrettyNum.objects.filter(mobile="188888888").first()
    
    # True/False
    obj = models.PrettyNum.objects.filter(mobile="188888888").exists()
    
  • 编辑:【正则表达式】【手机号不能存在】

    排除自己以外,其他的数据是否手机号是否重复?
    
    # id!=2 and mobile='1888888888'
    models.PrettyNum.objects.filter(mobile="188888888").exclude(id=2)
    

9.5搜索手机号

models.PrettyNum.objects.filter(mobile="188888888"id=12)

data_dict = {"mobile": "199999991","id":123}
models.PrettyNum.objects.filter(**data_dict)
models.PrettyNum.objects.filter(id=12)         # 等于12
models.PrettyNum.objects.filter(id_gt=12)      # 大于12
models.PrettyNum.objects.filter(id_gte=12)     # 大于等于12
models.PrettyNum.objects.filter(id_lt=12)      # 小于12
models.PrettyNum.objects.filter(id_lte=12)     # 小于等于12

data_dict = {"id_lte":123}
models.PrettyNum.objects.filter(**data_dict)
models.PrettyNum.objects.filter(mobile="999")                     # 等于
models.PrettyNum.objects.filter(mobile_startswith="1999")         # 筛选出以1999开头
models.PrettyNum.objects.filter(mobile_endswith="999")            # 筛选出以999结尾
models.PrettyNum.objects.filter(mobile_contains="999")            # 筛选出包含999

data_dict = {"mobile_contains": "999"}
models.PrettyNum.objects.filter(**data_dict)

9.6分页

queryset = models.PrettyNum.objects.all()

queryset = models.PrettyNum.objects.filter(id=1)[0:10]

# 第1页
queryset = models.PrettyNum.objects.all()[0:10]

# 第2页
queryset = models.PrettyNum.objects.all()[10:20]

# 第3页
queryset = models.PrettyNum.objects.all()[20:30]
data = models.PrettyNum.objects.all().count()
data = models.PrettyNum.objects.filter(id=1).count()
  • 分页的逻辑和处理规则

  • 封装分页类

    • 从头写到尾开发
    • 写项目用【pagination.py】公共组件
  • 小Bug,搜索+分页情况下。

    分页时候,保留原来的搜索条件
    
    http://127.0.0.1:8000/pretty/list/?q=888
    http://127.0.0.1:8000/pretty/list/?page=1
    
    http://127.0.0.1:8000/pretty/list/?q=888&page=12
    

10.时间插件

<link rel="stylesheet" href="static/plugins/bootstrap-3.4.1/css/bootstrap.css">
<link rel="stylesheet" href="static/plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css">


<input type="text" id="dt" class="form-control" placeholder="入职日期">


<script src="static/js/jquery-3.7.1.min.js"></script>
<script src="static/plugins/bootstrap-3.4.1/js/bootstrap.js"></script>
<script src="static/plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.js"></script>
<script src="static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js"></script>


<script>
    $(function () {
        $('#dt').datetimepicker({
            format: 'yyyy-mm-dd',
            startDate: '0',
            language: "zh-CN",
            autoclose: true
        })
    })
</script>

11.ModelForm和BootStrap

  • ModelForm可以帮助我们生成HTML标签。

    class UserModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password',]
    
    form = UserModelForm()
    
    {{form.name}}          普通的input框
    {{form.password}}      普通的input框
    
  • 定义插件

    class UserModelForm(forms.ModelForm):
        name = forms.CharField(min_length=3, label="用户名")
    
        # password = forms.CharField(validators= label="密码")
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password',]
            
            widgets = {
                'name': forms.TextInput(attrs={'class': 'form-control'}),
                'password': forms.TextInput(attrs={'class': 'form-control'}),
            }
    
    class UserModelForm(forms.ModelForm):
        name = forms.CharField(
            min_length=3,
            label="用户名",
            widget=forms.TextInput(attrs={'class': 'form-control'})
        )
    
        # password = forms.CharField(validators= label="密码")
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password', 'age']
    
    {{form.name}}          Bootstrap的input{{form.password}}      Bootstrap的input
  • 重新定义的init方法,批量设置

    class UserModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password', 'age',]
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
            # 循环ModelForm中的所有字段,给每个字段的插件设置
            for name, field in self.fields.items():
                field.widget.attrs = {
                    'class': 'form-control',
                    'placeholder': field.label
                }
    
    class UserModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password', 'age',]
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
            # 循环ModelForm中的所有字段,给每个字段的插件设置
            for name, field in self.fields.items():
                # 字段中有属性,保留原来的属性,没有属性,才增加。
                if field.widget.attrs:
                    field.widget.attrs["class"] = 'form-control'
                    field.widget.attrs["placeholder"] = field.label
                else:
                    field.widget.attrs = {
                        'class': 'form-control',
                        'placeholder': field.label
                    }
    
    class UserEditModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password', 'age',]
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
            # 循环ModelForm中的所有字段,给每个字段的插件设置
            for name, field in self.fields.items():
                # 字段中有属性,保留原来的属性,没有属性,才增加。
                if field.widget.attrs:
                    field.widget.attrs["class"] = 'form-control'
                    field.widget.attrs["placeholder"] = field.label
                else:
                    field.widget.attrs = {
                        'class': 'form-control',
                        'placeholder': field.label
                    }
    
  • 自定义类

    class BootStrapModelForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
          super().__init__(*args, **kwargs)
    
            # 循环ModelForm中的所有字段,给每个字段的插件设置
            for name, field in self.fields.items():
                # 字段中有属性,保留原来的属性,没有属性,才增加。
                if field.widget.attrs:
                    field.widget.attrs["class"] = 'form-control'
                    field.widget.attrs["placeholder"] = field.label
                else:
                    field.widget.attrs = {
                        'class': 'form-control',
                        'placeholder': field.label
                    }
    
    class UserEditModelForm(BootStrapModelForm):
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password', 'age',]
    

操作

12.管理员操作

在这里插入图片描述

13.用户登录

什么是cookie和session?

在这里插入图片描述

13.1登录

登录成功后:

  • cookie,随机字符串
  • session,用户信息

在其他需要登录才能访问的页面中,都需要加入:

def index():
    info = request.session.get("info")
    if not info:
        return redirect("/login/")
        
    ...

目标:在18个视图函数前面统一加入判断。

info = request.session.get("info")
if not info:
    return redirect("/login/")
13.2中间件的体验

在这里插入图片描述

  • 定义中间件

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    
    class M1(MiddlewareMixin):
        """ 中间件1 """
    
        def process_request(self, request):
    
            # 如果方法中没有返回值(返回None),继续向后走
            # 如果有返回值 HttpResponse.
            print("M1.进来了")
            return HttpResponse("无权访问")
    
        def process_response(self, request, response):
            print("M1.走了")
    
            return response
    
    
    class M2(MiddlewareMixin):
        """ 中间件2 """
    
        def process_request(self, request):
            print("M2.进来了")
    
        def process_response(self, request, response):
            print("M2.走了")
    
            return response
    
    
  • 应用中间件setings.py

    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",
        "app01.middleware.auth.M1",
        "app01.middleware.auth.M2",
    ]
    
  • 在中间价的process_request方法

    # 如果方法中没有返回值(返回None),继续向后走
    # 如果有返回值 HttpResponse、render、redirect,则不在继续向后执行
    
13.3中间价实现登录校验
  • 编写中间价

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    from django.shortcuts import render, redirect
    
    
    class AuthMiddleware(MiddlewareMixin):
        def process_request(self, request):
            # 0、排除那些不需要登录就能访问的页面
            # request.path_info 获取当前用户请求的URL /login/
            if request.path_info == '/login/':
                return
            
            # 1、读取当前访问的用户的session信息,如果能读到,说明已经登录过,就可以继续向后走
            info_dict = request.session.get("info")
            if info_dict:
                return
    
            # 2、没有登录过,重新回到登录页面
            return redirect("/login/")
    
    
  • 应用中间价

    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",
        "app01.middleware.auth.AuthMiddleware",
    ]
    
13.4注销
def logout(request):
    """ 注销 """
    request.session.clear()

    return redirect('/login/')
13.5当前用户

在这里插入图片描述

在这里插入图片描述

14.图片验证码

在这里插入图片描述

14.1生成图片

pip install pillow
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter


def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
    code = []
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

    def rndChar():
        """
        生成随机字母
        :return:
        """
        return chr(random.randint(65, 90))

    def rndColor():
        """
        生成随机颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    # 写文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

    # 画干扰线
    for i in range(5):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)

        draw.line((x1, y1, x2, y2), fill=rndColor())

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, ''.join(code)


if __name__ == '__main__':
    # 1. 直接打开
    img, code = check_code()
    print(code)

    # 2. 写入文件
    # img,code = check_code()
    with open('code.png', 'wb') as f:
        img.save(f, format='png')

15.Ajax请求

浏览器向网站发送请求时:url和表单的形式提交。

  • GET
  • POST

特点:页面刷新。

除此之外,也可以基于Ajax向后台发送请求(偷偷的发送请求)

  • 依赖jQuery

  • 编写ajax代码

    $.ajax({
        url:"发送的地址",
        type:"get",
        data:{
            n1:123,
            n2:456
        },
        success:function(res){
            console.log(res);
        }
    })
    

15.1GET请求

$.ajax({
    url: '/task/ajax/',
    type: "get",
    data: {
        n1: 123,
        n2: 456
    },
    success: function (res) {
        console.log(res)
    }
})
from django.shortcuts import render, HttpResponse

def task_ajax(request):
    print(request.GET)

    return HttpResponse("成功了")

15.2POST请求

$.ajax({
    url: '/task/ajax/',
    type: "post",
    data: {
        n1: 123,
        n2: 456
    },
    success: function (res) {
        console.log(res)
    }
})
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt


def task_list(request):
    """ 任务列表 """

    return render(request, 'task_list.html')


@csrf_exempt
def task_ajax(request):
    print(request.GET)
    print(request.POST)

    return HttpResponse("成功了")

15.3关闭绑定事件

{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <h1>任务管理</h1>

        <h3>实例1</h3>
        <input id="btn1" type="button" class="btn btn-primary" value="点击">
    </div>
{% endblock %}

{% block js %}
    <script type="text/javascript">
        $(function () {
            // 页面框架加载完成之后代码自动执行
            bindBtn1Event();

        })

        function bindBtn1Event() {
            $("#btn1").click(function () {
                $.ajax({
                    url: '/task/ajax/',
                    type: "post",
                    data: {
                        n1: 123,
                        n2: 456
                    },
                    success: function (res) {
                        console.log(res)
                    }
                })

            })
        }


    </script>
{% endblock %}

15.4ajax请求的返回值

一般会返回JSON格式。

{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <h1>任务管理</h1>

        <h3>实例1</h3>
        <input id="btn1" type="button" class="btn btn-primary" value="点击">
    </div>
{% endblock %}

{% block js %}
    <script type="text/javascript">
        $(function () {
            // 页面框架加载完成之后代码自动执行
            bindBtn1Event();

        })

        function bindBtn1Event() {
            $("#btn1").click(function () {
                $.ajax({
                    url: '/task/ajax/',
                    type: "post",
                    data: {
                        n1: 123,
                        n2: 456
                    },
                    dataType: "JSON",
                    success: function (res) {
                        console.log(res);
                        console.log(res.status);
                        console.log(res.data);
                    }
                })

            })
        }


    </script>
{% endblock %}
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
from django.http import JsonResponse


def task_list(request):
    """ 任务列表 """

    return render(request, 'task_list.html')


@csrf_exempt
def task_ajax(request):
    print(request.GET)
    print(request.POST)
    data_dict = {"status": True, "data": [11, 22, 33, 44]}

    return HttpResponse(json.dumps(data_dict))
    # return JsonResponse(data_dict)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/505945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JMeter基础用法和测试WebSocket请求

目录 JMeter websocket插件安装测试接口的编写添加测试线程组创建取样器创建WebSocket连接创建循环控制器创建WebSocket request-response Sampler创建固定定时器 正则匹配上一个请求的数据做为当前请求参数正则编写使用匹配值 CSV文件读取参数添加汇总报告和结果树 JMeter web…

重读 Java 设计模式: 深入探讨原型模式,灵活复制对象

引言 在软件开发中&#xff0c;经常会遇到需要创建对象的情况。有时候&#xff0c;我们希望创建一个新的对象&#xff0c;但又不想通过传统的构造方法来创建&#xff0c;而是希望通过复制一个现有对象的方式来创建新的对象。这时&#xff0c;原型模式就能派上用场了。原型模式…

【漏洞复现】WordPress Plugin LearnDash LMS 敏感信息暴漏

漏洞描述 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 WordPress Plugin LearnDash LMS 4.10.2及之前版本存在安全漏洞&#x…

吴恩达2022机器学习专项课程(一) 4.4 学习率

问题预览/关键词 学习率太小有什么影响&#xff1f;学习率太大有什么影响&#xff1f;如果成本函数达到局部最小值&#xff0c;使用梯度下降还能继续最小化吗&#xff1f;为什么学习率固定&#xff0c;而最小化成本函数的步幅却越来越缓&#xff1f;如何选择合适的学习率&…

Mac 版 IDEA 中配置 GitLab

一、安装Git 在mac终端输入Git检测指令&#xff0c;可以通过git命令查看Git是否安装过&#xff0c;如果没有则会弹出安装按钮&#xff0c;如果安装过则会输出如下信息。 WMBdeMacBook-Pro:~ WENBO$ git usage: git [--version] [--help] [-C <path>] [-c namevalue][--…

Kafka 学习之:基于 flask 框架通过具体案例详解生产消费者模型,这一篇文章就够了

文章目录 案例信息介绍后端异步处理请求和后端同步处理请求同步方式异步方式 环境文件目录配置.envrequirements.txt 完整代码ext.pyapp.pykafka_create_user.py 运行方式本地安装 kafka运行 app.py使用 postman 测试建立 http 长连接&#xff0c;等待后端处理结果发送 RAW DAT…

Python之Opencv进阶教程(1):图片模糊

1、Opencv提供了多种模糊图片的方法 加载原始未经模糊处理的图片 import cv2 as cvimg cv.imread(../Resources/Photos/girl.jpg) cv.imshow(girl, img)1.1 平均值 关键代码 # Averaging 平均值 average cv.blur(img, (3, 3)) cv.imshow(Average Blur, average)实现效果 1.2…

this.$route.back()时的组件缓存

1.this.$route.back()回到上一个路径会重新加载 跳转时,前一个路由的内容会被销毁,当回来时,重新创建树,组件内有保存了距离,没有一开始是0. 2.keep-alive写在router-view上面,这个地方所代表的路由会被保存,因此可以写在上面,保存,当返回时,如果是这个路由,里面的内容是一样…

Linux学习:进程(4)程序地址空间(笔记)

目录 1. Linux下各种资源的内存分布2. 物理地址与虚拟(线性)地址3. 程序地址空间的区域划分4. 地址映射与页表5. 缺页中断 1. Linux下各种资源的内存分布 2. 物理地址与虚拟(线性)地址 在有关进程创建的初步学习中&#xff0c;我们了解了fork函数创建子进程的方式。此种进程的创…

云计算探索-如何在服务器上配置RAID(附模拟器)

一&#xff0c;引言 RAID&#xff08;Redundant Array of Independent Disks&#xff09;是一种将多个物理硬盘组合成一个逻辑单元的技术&#xff0c;旨在提升数据存取速度、增大存储容量以及提高数据可靠性。在服务器环境中配置RAID尤其重要&#xff0c;它不仅能够应对高并发访…

力扣Lc25--- 821. 字符的最短距离(java版)-2024年3月31日

1.题目描述 2.知识点 从左向右遍历&#xff1a; 这一遍历可以帮助我们找到每个位置到其左边最近的目标字符的距离。 从右向左遍历&#xff1a; 这一遍历可以帮助我们找到每个位置到其右边最近的目标字符的距离&#xff0c;并将这个距离与之前从左向右遍历得到的距离进行比较&…

腾讯云轻量2核2G3M云服务器优惠价格61元一年,配置详解

腾讯云轻量2核2G3M云服务器优惠价格61元一年&#xff0c;配置为轻量2核2G、3M带宽、200GB月流量、40GB SSD盘&#xff0c;腾讯云优惠活动 yunfuwuqiba.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云轻量2核2G云服务器优惠价格 腾讯云&#xff1a;轻量应用服务器100%CPU性能…

Linux速览(2)——环境基础开发工具篇(其一)

本章我们来介绍一些linux的常用工具 目录 一. Linux 软件包管理器 yum 1.什么是软件包? 2. 查看软件包 3. 如何安装软件 4. 如何卸载软件 5.yum补充 6. 关于 rzsz 二. Linux编辑器-vim使用 1. vim的基本概念 2. vim的基本操作 3. vim正常模式命令集 4. vim末行模式…

【核弹级软安全事件】XZ Utils库中发现秘密后门,影响主要Linux发行版,软件供应链安全大事件

Red Hat 发布了一份“紧急安全警报”&#xff0c;警告称两款流行的数据压缩库XZ Utils&#xff08;先前称为LZMA Utils&#xff09;的两个版本已被植入恶意代码后门&#xff0c;这些代码旨在允许未授权的远程访问。 此次软件供应链攻击被追踪为CVE-2024-3094&#xff0c;其CVS…

数据结构——二叉树——堆

前言&#xff1a; 在前面我们已经学习了数据结构的基础操作&#xff1a;顺序表和链表及其相关内容&#xff0c;今天我们来学一点有些难度的知识——数据结构中的二叉树&#xff0c;今天我们先来学习二叉树中堆的知识&#xff0c;这部分内容还是非常有意思的&#xff0c;下面我们…

docker-compose命令管理docker命令集合

Docker-Compose 简介 Docker-Compose 项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose 项目由 Python 编写&#xff0c;调用 Docker 服务提供的API来对容器进行管理。因此&#xff0c;只要所操作的平台支持 Docker API&#xff…

zookeeper如何管理客户端与服务端之间的链接?(zookeeper sessions)

zookeeper客户端与服务端之间的链接用zookeeper session表示。 zookeeper session有三个状态&#xff1a; CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY, CLOSED, AUTH_FAILED, NOT_CONNECTED&#xff08;start时的状态&#xff09; 1、CONNECTING 。 表明客户…

期货学习笔记-MACD指标学习1

MACD常规参数与优化参数降低容错率的使用技巧 MACD的基本概念及组成 概念 MACD是杰拉德 阿佩尔于1979年提出的&#xff0c;利用收盘价的短期&#xff08;常用为12日&#xff09;指数移动平均线与长期&#xff08;常用为26日&#xff09;指数移动平均线之间的聚合与分离情况&a…

【Gd2O3】Gd2O3栅极电介质增强GaN器件的可靠性

【Effects of Gd2O3 Gate Dielectric on Proton-Irradiated AlGaN/GaN HEMTs】 概括总结&#xff1a; 该研究探讨了质子辐射对使用Gd2O3作为栅极电介质的AlGaN/GaN高电子迁移率晶体管&#xff08;HEMTs&#xff09;的影响。通过对比肖特基栅极HEMTs和MOS-HEMTs在2 MeV质子辐射…

基础布局之LinearLayout线性布局

目录 一、基础属性二、重点属性2.1 weight(权重)属性&#xff1a;2.2 gravity 一、基础属性 LinearLayout默认方向是水平排放 属性作用android:id控件的ID&#xff0c;可以通过这个ID号来找到对应的控件android:layout_width控件的宽度android:layout_height控件的高度androi…