六、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)



















