首页 > 其他分享 >(学习日记)六、Ajax请求

(学习日记)六、Ajax请求

时间:2024-02-16 13:57:13浏览次数:24  
标签:function status 请求 form res request Ajax data 日记

15.Ajax请求

浏览器向网站发送请求时:

  • GET
  • POST

特点:页面会刷新。

也可以基于Ajax向后台发送请求(偷偷发送请求)

  • 依赖jQuery

  • 编写ajax

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

15.1GET请求

<script type="text/javascript">
    function clickMe() {
        $.ajax({
            url:'/task/ajax/',
            type:"get",
            data:{
                n1:123,
                n2:456,
            }, 
            success:function (res) {
                console.log(res);
            }
        })
    }
</script>
def task_ajax(request):
    print(request.GET)
    return HttpResponse("成功了")

15.2POST请求

<script type="text/javascript">
    function clickMe() {
        $.ajax({
            url:'/task/ajax/',
            type:"post",
            data:{
                n1:123,
                n2:456,
            }, 
            success:function (res) {
                console.log(res);
            }
        })
    }
</script>
@csfr_exempt
def task_ajax(request):
    print(request.POST)
    return HttpResponse("成功了")

15.3使用jQuery绑定事件

{% extends "layout.html" %}

{% block title %}
任务管理
{% endblock %}
{% block css %}
<style>

</style>
{% endblock  %}
{% block content %}
    <div class="container">
        <h1>任务列表</h1>
        <h3>示例1</h3>
        <input type="button" class="btn btn-primary" value="点击" id="btn1">
    </div>
{% endblock  %}
{% block js %}
    <script type="text/javascript">
        $(function () {  
            // 页面框架加载完成之后代码自动执行
            bindBtn1Event();

        })


        //绑定在btn1上的事件
        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.4 ajax请求的返回值

一般不会返回页面,而是一个JSON格式

{% block content %}
<h3>示例1</h3>
<input type="button" class="btn btn-primary" value="点击" id="btn1">
{% endblock %}
{% block js %}
    <script type="text/javascript">
        $(function () {  
            // 页面框架加载完成之后代码自动执行
            bindBtn1Event();

        })
        //绑定在btn1上的事件
        function bindBtn1Event() {
            $("#btn1").click(function () {
                $.ajax({
                    url:'/task/ajax/',
                    type:'post',
                    data:{
                        n1:123,
                        n2:456,
                    },
                    dataType:"JSON",//通过逆序列化将字典变成JSON文件,之后可以通过.key获取值
                    success: function (res) {
                        console.log(res.status);
                        console.log(res.data);
                    }
                });
            })
        }
    </script>
{% endblock %}
# 用装饰器直接跳过csfr_token
@csrf_exempt
def task_ajax(request):
    """Ajax"""
    data_dict = {"status": True, "data": [11, 22, 33, 44]}
    # 对json格式进行dump生成字典,否则输出为object[JSON]
    json_string = json.dumps(data_dict)
    # return JsonResponse(data_dict)
    return HttpResponse(json_string)

含有input框的请求

<h3>示例2</h3>
<input type="text" id="txtUser" placeholder="姓名">
<input type="number" id="txtAge" placeholder="年龄">
<input type="submit" class="btn btn-primary" value="提交" id="btn2">
<script>
//绑定在btn2上的事件
function bindBtn2Event() {
    $("#btn2").click(function () {
        $.ajax({
            url:'/task/ajax/',
            type:'post',
            //获取input的值,提交到后台
            data:{
                n1:$("#txtUser").val(),
                n2:$("#txtAge").val(),
            },
            dataType:"JSON",//通过逆序列化将字典变成JSON文件,之后可以通过.key获取值
            success: function (res) {
                console.log(res.status);
                console.log(res.data);
            }
        });
    })
}
</script>

含有多个input框 - 使用form + name

<h3>示例3</h3>
<form id="form3">
    <input type="text" name="user" placeholder="姓名">
    <input type="text" name="age" placeholder="年龄">
    <input type="text" name="email" placeholder="邮件">
    <input type="text" name="more" placeholder="更多">
</form>
<input type="submit" class="btn btn-primary" value="提交" id="btn3">
<script>
//绑定在btn3上的事件
function bindBtn3Event() {
    $("#btn3").click(function () {
        $.ajax({
            url:'/task/ajax/',
            type:'post',
            //获取input的值,提交到后台
            data:$("#form3").serialize(),
            dataType:"JSON",//通过逆序列化将字典变成JSON文件,之后可以通过.key获取值
            success: function (res) {
                console.log(res.status);
                console.log(res.data);
            }
        });
    })
}
</script>

15.5通过Ajax添加数据

{% block content %}
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">表单</div>
            <div class="panel-body"> 
                <form id="formAdd" novalidate>
                    <div class="col-xs-6">
                        <div class="clearfix">
                            <div class="form-group" style="position:relative;">
                                <label>{{ form.title.label }}</label>
                                {{ form.title }}
                                <span class="error_msg" style="color:red;position:absolute;"></span>
                            </div>
                            <div class="form-group" style="position:relative;">
                                <label>{{ form.level.label }}</label>
                                {{ form.level }}
                                <span class="error_msg" style="color:red;position:absolute;"></span>
                            </div>
                            <div class="form-group" style="position:relative;">
                                <label>{{ form.user.label }}</label>
                                {{ form.user }}
                                <span class="error_msg" style="color:red;position:absolute;"></span>
                            </div>
                            <button id="btnAdd" type="button" class="btn btn-primary">提 交</button>
                        </div>
                    </div>
                    <div class="col-xs-6">
                        <div class="clearfix">
                            <div class="form-group" style="position:relative;">
                                <label>{{ form.detail.label }}</label>
                                {{ form.detail }}
                                <span class="error_msg" style="color:red;position:absolute;"></span>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock  %}
{% block js %}
    <script type="text/javascript">
        $(function () {  
            // 页面框架加载完成之后代码自动执行
            btnAddEvent()

        })

        //绑定在btnAdd上的事件
        function btnAddEvent() {
            $("#btnAdd").click(function () {
                $(".error_msg").empty();//先将错误信息置为空

                $.ajax({
                    url:'/task/add/',
                    type:'post',
                    data:$("#formAdd").serialize(),
                    dataType:"JSON",
                    success:function (res) {
                        if(res.status){
                            alert("添加成功")
                        }else{
                            $.each(res.error, function (name, data){
                                console.log(name, data);
                                $("#id_" + name).next().text(data[0])
                            })
                        }
                    }
                })
            })            
        }

        
    </script>
{% endblock  %}

views -> task.py

@csrf_exempt
def task_add(request):
    """添加任务"""
    print(request.POST)
    # <QueryDict: {'title': [''], 'level': ['1'], 'user': [''], 'detail': ['']}>

    # 1.用户发送过来的数据进行校验(ModelForm)
    form = TaskModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        # 不能使用redirect跳转,因为ajax在发送时候不修改页面, 可以返回一个json给页面,然后页面根据对应的内容进行操作
        status_dict = {"status": True}
        return HttpResponse(json.dumps(status_dict))
    status_dict = {"status": False, "error": form.errors}
    return HttpResponse(json.dumps(status_dict, ensure_ascii=False))

utils -> modelform.py

class TaskModelForm(BootStrapModelForm):
    class Meta:
        model = models.Task
        fields = ["title", "level", "user", "detail"]
        widgets = {
            # "detail":forms.TextInput,     text框
            # "detail": forms.Textarea,     textarea框
        }

16.知识点回顾

  • 创建Django项目
django-admin startproject xxx
  • 创建APP & 注册APP
python manage.py startapp yyy
INSTALLED_APP = {
    ...
    'app01.apps.App01Config'
}

不注册APP则无法创建models.py中的表到数据库中

  • 配置静态文件路径 & 模板的路径

  • 配置数据库相关的操作

    • 第三方模块(django3版本)

      pip install mysqlclient
      
    • 先去MySQL中创建一个数据库

    • 配置和数据库的连接 settings.py文件

    • 在app下的models.py中编写数据库文件(如果使用sqlite3数据库,直接从这一步开始即可)

    • 执行makemigrations和migrate

  • urls.py -> 路由 URL和函数的对应关系

  • views.py 视图函数 编写业务逻辑

  • templates目录, 编写HTML模板 模板语法、继承、

  • ModelForm & Form组件,在开发增删改查时候

    • 生成HTML标签(生成默认值)
    • 请求数据进行校验(钩子方法, 正则)
    • 保存到数据库(ModelForm)
    • 获取错误请信息(ErrorValidation 和 add_errors)
  • Cookie和Session,保存用户的登录信息

  • 中间件,基于中间件实现用户认证,基于:process_request

  • ORM操作

    mdoels.User.objects.filter(id="xxx")
    
  • 分页组件的应用

订单

  • 表结构

        class Order(models.Model):
            """订单"""
    
            oid = models.CharField(verbose_name="订单号", max_length=64)
            title = models.CharField(verbose_name="名称", max_length=32)
            price = models.IntegerField(verbose_name="价格")
    
            status_choices = (
                (1, "待支付"),
                (2, "已支付"),
            )
            status = models.SmallIntegerField(
                verbose_name="状态", choices=status_choices, default=1
            )
            admin = models.ForeignKey(
                verbose_name="管理员", to="Admin", on_delete=models.CASCADE
            )
    

想要去数据库中获取数据时:对象/字典

# 对象当前行的所有数据
row_object = models.Order.objects.filter(id=uid).first()
row_object.id
row_object.title
# 取某几列,字典类(因为json)
row_object = models.Order.objects.filter(id=uid).values("id","title").first()
# queryset = [obj, obj, obj]
queryset = models.Order.objects.all()

# queryset = [{"id":xx, "title":yy }, {}, {}]
queryset = models.Order.objects.all().values("id", "title")
#queryset = [(), (), ()]
queryset = models.Order.objects.all().values_list("id"m "title")

views -> order.py

from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
from django import forms
import random
from datetime import datetime

from app01 import models
from app01.utils.bootstrap_form import BootStrapModelForm
from app01.utils.pagination import Pagination


class OrderModelForm(BootStrapModelForm):

    class Meta:
        model = models.Order
        # fields = "__all__"
        # 订单号由系统生成
        exclude = ["oid", "admin"]


def order_list(request):
    queryset = models.Order.objects.all().order_by("-id")
    page_object = Pagination(request, queryset)

    form = OrderModelForm()

    return render(
        request,
        "order_list.html",
        {
            "form": form,
            "queryset": page_object.page_queryset,
            "page_string": page_object.html(),
        },
    )


@csrf_exempt
def order_add(request):
    """新建订单(Ajax请求)"""
    form = OrderModelForm(data=request.POST)
    if form.is_valid():
        # 缺少oid
        # 生成一个以 年月日时分秒 + 随机生成值 构建的oid
        form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(
            random.randint(1000, 9999)
        )
        # 管理员 当外键为admin时候,实际上数据库中存储的是admin_id字段 为其添加当前系统的登录的管理员
        form.instance.admin_id = request.session["info"]["id"]
        form.save()
        # 等价于HttpResponse(json.dumps({"status":True}))
        return JsonResponse({"status": True})
    """console.log(res)
    {
        "status": false,
        "error": {
            "title": ["这个字段是必填项。"],
            "price": ["这个字段是必填项。"],
            "admin": ["这个字段是必填项。"],
        }
    }
    """
    return JsonResponse({"status": False, "error": form.errors})


def order_delete(request):
    """删除订单"""
    uid = request.GET.get("uid")
    exsits = models.Order.objects.filter(id=uid).exists()
    if exsits:
        models.Order.objects.filter(id=uid).delete()
        return JsonResponse({"status": True})
    return JsonResponse({"status": False, "error": "数据不存在,删除失败"})


def order_detail(request):
    """根据ID获取订单详细"""
    uid = request.GET.get("uid")
    row_dict = (
        models.Order.objects.filter(id=uid).values("title", "price", "status").first()
    )
    if not row_dict:
        return JsonResponse({"status": False, "error": "数据不存在,删除失败"})
    """方式一 字典

    result = {
        "status": True,
        "data": {
            "title": row_object.title,
            "price": row_object.price,
            "status": row_object.status,
        },
    }    
    """
    return JsonResponse({"status": True, "data": row_dict})

    # 从数据库中获取一个对象 row_object


@csrf_exempt
def order_edit(request):
    """编辑页面"""
    uid = request.GET.get("uid")
    row_object = models.Order.objects.filter(id=uid).first()
    if not row_object:
        # 编辑的内容不存在(编辑时已被删除)
        return JsonResponse({"status": False, "tips": "数据不存在,请重试"})
    form = OrderModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        form.save()
        return JsonResponse({"status": True})
    # 编辑的内容不符合规定
    return JsonResponse({"status": False, "error": form.errors})

templates ->order_list.py

{% extends "layout.html" %}

{% block title %}
订单管理
{% endblock %}
{% block css %}
<style>
  .unoccupied{
    background-color: red;
    color: #FFFFFF;
  }
</style>
{% endblock  %}
{% block 订单管理 %}class="active"{% endblock %}
{% block content %}
    <div class="container">
        <input type="button" value="新建订单1" class="btn btn-success" id="btnAdd">

        <input type="button" value="新建订单2" class="btn btn-success" data-toggle="modal" data-target="#myModal">

        <div class="panel panel-default" style="height:460px;margin-top:20px;">

          <div class="panel-heading">
              <h3 class="panel-title"><i class="fa fa-list-ul"></i> 订单列表</h3>
          </div>

          <table class="table table-hover table-bordered" style="padding:0 20px 0 20px;">
              <thead>
                  <tr>
                      <th>ID</th>
                      <th>订单号</th>
                      <th>名称</th>
                      <th>价格</th>
                      <th>状态</th>
                      <th>管理员</th>
                      <th>操作</th>
                  </tr>
              </thead>
              <tbody>
                  {% for item in queryset %}
                  <tr uid="{{ item.id }}">
                      <td>{{ item.id }}</td>
                      <td>{{ item.oid}}</td>
                      <td>{{ item.title}}</td>
                      <td>{{ item.price }}</td>
                      <td 
                      {% if item.status == 1 %}
                          class="unoccupied"
                      {% endif %}                     
                      >{{ item.get_status_display }}</td>
                      <td>{{ item.admin.username }}</td>                      
                      <td>
                          <input  uid={{ item.id }} type="button" class="btn btn-primary btn-xs btn-edit" value="编辑">
                          <span> </span>
                          <input  uid={{ item.id }} type="button" class="btn btn-danger btn-xs btn-delete" value="删除">
                      </td>
                  </tr>
                  {% endfor %}
              </tbody>
          </table>

      </div><!--panel-->

      <ul class="pagination">
          {{ page_string }}
      </ul>
    </div>


<!-- 新建/编辑订单对话框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
              <h4 class="modal-title" id="myModalLabel"></h4>
            </div>

            <div class="modal-body">

                <form id="formAdd" novalidate>

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

              </div>
              
              <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" id="BtnSave">保存</button>
              </div>
        </div>
    </div>
</div>

<!-- 删除订单对话框 -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
      <div class="alert alert-danger alert-dismissible fade in" role="alert">
        <h4>确认删除?</h4>
        <p style="margin:10px;">删除后所有关联的相关数据都会被删除</p>
        <p style="text-align:right;">
          <button id="btn-confrim-delete" type="button" class="btn btn-danger">确认</button>
          <!-- data-dismiss="modal" 取消对话框 -->
          <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
        </p>
      </div>
    </div>
</div>

{% endblock  %}
{% block js %}
<script type="text/javascript">
  var DELETE_ID ;
  var EIDT_ID ;
    $(function () {
        bindBtnAddEvent();
        bindBtnSaveEvent();
        bindBtnDeleteEvent();
        bindBtnConfirmDeleteEvent();
        bindBtnEditEvent();
    })

    function bindBtnAddEvent() {
        $("#btnAdd").click(function () {
          //将正在编辑的ID设置为空
          EIDT_ID = undefined;
          //清空由Edit留下的数据 $()[0]是对应的DOM
          $("#formAdd")[0].reset()
          //清除所有错误信息
          $(".error_msg").empty();          
          //点击按钮,显示对话框
          $("#myModal").modal('show');
          //修改对话框标题
          $("#myModalLabel").text("新建")            
        })
    }
    function bindBtnSaveEvent() {
        $("#BtnSave").click(function () {
          //清除所有错误信息
          $(".error_msg").empty(); 

          //根据EDIT_ID来确认当前保存的是新建数据还是编辑数据
          if(EIDT_ID){
            //编辑
            doEdit();
          }else{
            //添加
            doAdd();
          }
        });
    }
    function bindBtnDeleteEvent() {
      $(".btn-delete").click(function () {
        //显示删除对话框
        $("#deleteModal").modal('show');

        //获取当前行的id并赋值给全局变量
        DELETE_ID = $(this).attr("uid")

      })
    }
    function bindBtnConfirmDeleteEvent() {
      $("#btn-confrim-delete").click(function () {
        //点击确认删除按钮
        $.ajax({
          url:"/order/delete/", // => /order/delete/?uid=13
          type:"GET",
          data:{
            uid:DELETE_ID,
          },
          dataType:"JSON",
          success:function (res) {
            if(res.status){
              //alert("删除成功")
              //隐藏删除对话框
              $("#deleteModal").modal('hide');
              // //删除该行数据 通过js删除
              // $("tr[uid="+ DELETE_ID + "]").remove()

              //刷新页面
              location.reload()

              

              
            }else{
              alert(res.error)
            }
          }

        })
      });
    }
    function bindBtnEditEvent() {
      $(".btn-edit").click(function () {
        //当前id
        var currentId = $(this).attr("uid");
        EIDT_ID = currentId;
        console.log(EIDT_ID)


        //修改对话框标题
        $("#myModalLabel").text("编辑");

        //发送ajax去后端获取当前行的相关数据
        $.ajax({
          url:"/order/detail/",
          type:"get",
          data:{
            uid:currentId,
          },
          dataType:"JSON",
          success: function (res) {
            if(res.status){
              // 点击显示模态对话框
              $("#myModal").modal("show");  
              
              //console.log(res);
              //将数据默认赋值到对话框的标签中
              $.each(res.data, function (name, value) {
                $("#id_"+name).val(value);
              })
            }else{
              alert(res.error);
            }
          }
        })


      });
    }
    function doAdd(){
      $.ajax({
        url:"/order/add/",
        type:"post",
        data:$("#formAdd").serialize(),
        dataType:"JSON", //将从页面获取到的数据转化为JSON格式
        success:function (res){
          if(res.status){
            alert("创建成功");
            //清空表单 jQuery对象[0] - 找到对应的DOM对象 .reset 使用DOM对象的reset置空功能
            $("#formAdd")[0].reset();
            //关闭对话框
            $("#myModal").modal("hide");
            //重新加载页面
            location.reload()
          }else{
            //console.log(res.error)
            //将错误信息显示在对话框中
            $.each(res.error, function (name, errorList) {
              //拼接id id_title
              $("#id_" + name).next().text(errorList[0]);
            })
          }
        }
      })
    }
    function doEdit(){
      $.ajax({
        url:"/order/edit/?uid="+EIDT_ID,
        type:"post",
        data:$("#formAdd").serialize(),
        dataType:"JSON", //将从页面获取到的数据转化为JSON格式
        success:function (res){
          if(res.status){
            alert("创建成功");
            //清空表单 jQuery对象[0] - 找到对应的DOM对象 .reset 使用DOM对象的reset置空功能 等价于.val("")置空
            $("#formAdd")[0].reset();
            //关闭对话框
            $("#myModal").modal("hide");
            //重新加载页面
            location.reload()

          }else{
            //编辑的数据不存在
            if(res.tips){
              alert(res.tips)
            }else{


            }
            //console.log(res.error)
            //将错误信息显示在对话框中
            $.each(res.error, function (name, errorList) {
              //拼接id id_title
              $("#id_" + name).next().text(errorList[0]);
            })
          }
        }
      })
    }

</script>
{% endblock  %}

17.其他知识点

1.图表

  • highchart
  • echarts(推荐)

柱状图

views -> chart.py

def chart_bar(request):
    """构造柱状图数据"""
    # 数据可以去数据库中获取
    legend = ["销量", "业绩"]
    series_list = [
        {"name": "销量", "type": "bar", "data": [5, 20, 36, 10, 10, 20]},
        {"name": "业绩", "type": "bar", "data": [6, 24, 44, 50, 10, 60]},
    ]
    x_axis = ["1月", "2月", "3月", "4月", "5月", "6月"]
    result = {
        "status": True,
        "data": {
            "legend": legend,
            "series_list": series_list,
            "x_axis": x_axis,
        },
    }
    return JsonResponse(result)

templates -> chart_list.html

<div class="col-sm-4">

    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">饼状图</h3>
        </div>
        <div class="panel-body">
            <div id="m3" style="width:100%;height:400px;"></div>
        </div>

    </div><!--panel-->

</div>

...

<script src="{% static 'js/echarts.js' %}"></script>
<script type="text/javascript">
    $(function () {
      InitBar();
    })

    /*初始化柱状图*/
    function InitBar() {
      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById('m2'));

      // 指定图表的配置项和数据
      var option = {
        title: {
          text: 'ECharts 入门示例',
          textAlign:"auto",
          left:"center",
        },
        tooltip: {},
        legend: { //后台获取
          bottom:0,
        },
        xAxis: {
          data: [] //后台获取
        },
        yAxis: {},
        series: [] //后台获取
      };
      $.ajax({
        url:"/chart/bar/",
        type:"get",
        dataType:"JSON",
        success:function(res){
          //将后台返回的数据更新到option中
          if(res.status){
            option.legend.data = res.data.legend;
            option.xAxis.data = res.data.x_axis;
            option.series = res.data.series_list;
            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);            
          }//res.status

        },//success:function(res)

      })//$.ajax
        
    }//function InitBar()
</script>

2.关于文件的上传

2.1基本操作

<div class="container">
    <form method="post" enctype="multipart/form-data"><!--表单中一定要有enctype属性,否则不会上传文件-->
        {% csrf_token %}
        <input type="text" name="username">
        <input type="file" name="avatar">
        <input type="submit" value="提交">
    </form>
</div>
def upload_list(request):
    """上传文件"""
    if request.method == "GET":
        return render(request, "upload_list.html")
    # <QueryDict: {'username': ['朱一凡'], 'avatar': ['推荐-划分区域.png']}> 仅上传了文件的字符名而非文件
    # print(request.POST)  # 请求体中的数据(不包含文件)
    # print(request.FILES)  # 请求体中的文件
    file_object = request.FILES.get("avatar")  # 文件对象
    print(file_object.name)  # 文件名 推荐-划分区域.png

    # 将上传的文件写入一张图片中
    # 将图片分块上传,然后分块写入到a1.png中,也可以将文件名设置为file_object.name
    f = open("a1.png", mode="wb")
    for chunk in file_object:
        f.write(chunk)
    f.close

    return HttpResponse("提交成功")

案例:批量上传数据

<div class="panel-heading">
    <h3 class="panel-title"><i class="fa fa-list-ul"></i> 批量上传</h3>
</div>
<div class="panel-body">
    <form action="/depart/multi/" enctype="multipart/form-data" method="post">
        {% csrf_token %}
        <div class="form-group">
          <input type="file" name="exc">
        </div>
        <button type="submit" class="btn btn-info btn-sm">上传</button>
    </form>
</div>
def depart_multi(request):
    """批量上传(Excel文件)"""
    from openpyxl import load_workbook

    # 获取用户上传的文件对象
    file_object = request.FILES.get("exc")

    # 对象传递给openpyxl, 由openpyxl读取文件的内容
    wb = load_workbook(file_object)
    # 读取第一个sheet
    sheet = wb.worksheets[0]
    # cell = sheet.cell(1, 1)
    # 循环获取每一行的数据
    for row in sheet.iter_rows(min_row=2):
        # 获取每一行的第一个数据,即部门名称
        text = row[0].value
        # 判断该部门是否存在
        exists = models.Department.objects.filter(title=text).exists()
        if not exists:
            models.Department.objects.create(title=text)
        else:
            return HttpResponse("上传失败,有重复名称的部门")

    return redirect("/depart/list/")

案例:混合数据上传

提交页面时:用户输入数据 + 文件 (进行校验 不能为空,格式错误等)

  • Form生成HTML标签:type=file
  • 可以做表单的验证
  • form.cleaned_data获取 数据 + 文件对象
{% extends "layout.html" %}
{%load static%}

{% block title %}
{{ title_templ }}
{% endblock %}
{% block Form上传 %}class="active"{% endblock  %}
{% block content %}
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">
            <h3 class="panel-title">{{ panel_title_templ}}</h3>
            </div>

            <div class="panel-body">
                <form method="post" enctype="multipart/form-data" 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"><i class="fa fa-save" aria-hidden="true"></i> 保 存</button>
                    <a href="{{cancel_url}}" class="btn btn-danger" ><i class="fa fa-close" aria-hidden="true"></i> 取 消</a>
                </form>
            </div>
            
        </div>
    </div>
{% endblock  %}

from django import forms


class UpForm(BootStrapForm):
    bootstrap_exclude = ["img"]
    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


import os
from app01 import models


def upload_form(request):
    context = {"title_templ": "Form上传", "panel_title_templ": "Form上传"}
    if request.method == "GET":
        form = UpForm()
        return render(request, "upload_form.html", {**context, "form": form})
    # 进行表单验证要分别对数据和files进行验证
    form = UpForm(data=request.POST, files=request.FILES)
    if form.is_valid():
        # print(form.cleaned_data)
        # {'name': 'wupeiqi', 'age': 12, 'img': <InMemoryUploadedFile: a1.png (image/png)>}
        # 读取字段的数据然后分别对每个字段进行处理
        img_object = form.cleaned_data.get("img")
        # file_path = "app01/static/img/{}".format(img_object.name) project6-Django\System_Manage_User\app01\static
        # 数据库上传的地址,是在网页端通过与服务器地址拼接可以直接访问的
        db_file_path = os.path.join(
            "static",
            "img",
            img_object.name,
        )
        # 实际上文件的地址,即在存储图片时候的地址
        file_path = os.path.join(
            "project6-Django", "System_Manage_User", "app01", db_file_path
        )
        f = open(file_path, mode="wb")
        for chunk in img_object.chunks():
            f.write(chunk)
        f.close()

        # 将图片路径写入数据库
        models.Boss.objects.create(
            name=form.cleaned_data["name"],
            age=form.cleaned_data["age"],
            img=db_file_path,
        )

        return HttpResponse("上传成功")
    return render(request, "upload_form.html", {**context, "form": form})

2.2 启用media

在urls.py中进行配置

from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
	re_path(r"^media/(?P<path>.*)$", serve, {"document_root":settings.MEDIA_ROOT}, name="media"),
]

在settings.py中进行配置

import os

MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"

之后就可以直接通过/media/图片.png访问图片

案例:混合数据上传(Form)

def upload_form(request):
    context = {"title_templ": "Form上传", "panel_title_templ": "Form上传"}
    if request.method == "GET":
        form = UpForm()
        return render(request, "upload_form.html", {**context, "form": form})
    # 进行表单验证要分别对数据和files进行验证
    form = UpForm(data=request.POST, files=request.FILES)
    if form.is_valid():
        from django.conf import settings

        # media_path = os.path.join(settings.MEDIA_ROOT, img_object.name) 绝对路径
        media_path = os.path.join("media", img_object.name)
        # 实际上文件的地址,即在存储图片时候的地址
        file_path = os.path.join("project6-Django", "System_Manage_User", media_path)
        f = open(file_path, mode="wb")
        for chunk in img_object.chunks():
            f.write(chunk)
        f.close()

        # 将图片路径写入数据库
        models.Boss.objects.create(
            name=form.cleaned_data["name"],
            age=form.cleaned_data["age"],
            img=media_path,
        )

        return HttpResponse("上传成功")
    return render(request, "upload_form.html", {**context, "form": form})

2.3modelform

models.py

class City(models.Model):
    """城市"""

    name = models.CharField(verbose_name="名称", max_length=32)
    count = models.IntegerField(verbose_name="人口")
    # 本质上数据库中也是CharField,但是在保存时候
    img = models.FileField(
        verbose_name="LOGO", max_length=128, upload_to="city/"
    )  # 自动放到media下的city目录中

小结

  • 自己动手写

    file_object = request.FILES.get("exc")
    
  • Form组件(表单验证)

    request.POST
    file_object = request.FILES.get("exc")
    
    具体文件操作需要手动
    
  • ModelForm(表单验证 + 自动保存数据库 + 自动保存文件)

    - Media文件夹
    - Models.py定义类文件要
    img = models.FileField(verbose_name="", max_length=128, upload_to="fileAddress/")
    

标签:function,status,请求,form,res,request,Ajax,data,日记
From: https://www.cnblogs.com/gin49sz/p/18017069

相关文章

  • (学习日记)四、数据库MySQL
    1.初识网站默认编写的网站是静态的动态需要用到web框架的功能fromflaskimportFlask,render_templateapp=Flask(__name__)@app.route("/index")defindex():users={"Wu":"1","Liu":"2","Deng":"3"}#此处的数......
  • 频繁调一个http请求和多个不同http请求性能一样吗
    在讨论频繁调用一个HTTP请求和多个不同HTTP请求的性能时,我们需要考虑几个关键因素,包括网络延迟、服务器处理能力、请求的复杂性以及网络带宽等。在某些情况下,频繁调用一个HTTP请求可能和多个不同HTTP请求具有相似的性能,但在其他情况下,这两种做法可能会产生截然不同的结果。以下是......
  • Tauri http/https混用导致的请求失败的问题
    vite方案因为在项目里是需要使用http请求的,如果进行发布就会发现他的内置协议是https,导致http的请求发不出方案使用插件https://github.com/tauri-apps/plugins-workspace/tree/v1/plugins/localhost注意,我发现会闪退,文档上的例子去掉setup就好了(不知道为啥)路径:src......
  • Java学习日记 Day16 正月初五,学习回归正轨!
    年前把SSM和Linux学完了,过年期间简单的做了个ssm的项目,再理解理解SSM。今天继续学了radis,也是比较重要的一个技术。radis:简单来说就是把数据存到缓存里的技术,常常和关系数据库结合使用,我们可以把数据库拿出来的数据存到缓存里,这样减少了io的次数,大大提高了效率。radis的学习大......
  • 2024寒假年后集训日记
    2.14闲话做题纪要SP913QTREE2-QueryonatreeII\(LCA\)板子。点击查看代码structnode{ llnxt,to,w;}e[20002];llhead[20002],dep[20002],dis[20002],fa[20002][25],N,cnt=0;voidadd(llu,llv,llw){ cnt++; e[cnt].nxt=head[u]; e[cnt].to=v; e[cnt......
  • Nginx系列--转发请求的方法
    原文网址:​​Nginx系列--转发请求的方法_IT利刃出鞘的博客-CSDN博客​​简介说明本文介绍Nginx转发请求的方法。分享Java技术星球(自学精灵):​​https://learn.skyofit.com/​​需求用户访问aaa.com/bbb时,实际访问的是bbb123.com。方案1:return方法server{listen......
  • 爬虫_060_urllib post请求百度翻译的详细翻译
    目录百度翻译详细翻译接口关于复制的小技巧复制浏览器全部的requestheader代码百度翻译详细翻译接口这个接口,是我上一次用的接口,MD。关于复制的小技巧这个接口的参数数据就比较多了,我们都需要构建到data对象当中。这里可以第一步,先复制数据,然后粘贴到sublime当中。第二步......
  • 爬虫_059_urllib post请求百度翻译
    目录分析百度翻译找接口编写代码需要注意的点修改代码返回数据解析最后的说明分析百度翻译找接口编写代码importurllib.requestimporturllib.parseheaders={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)......
  • 爬虫_058_urllib get请求的urlencode方法
    目录urllib.parse.urlencode()quote方法使用的不是很经常的。因为quote的作用是将汉字转为百分号编码后的ASCII字符串。如果你的路径当中只有一个参数,你这样使用quote拼接一下url,这是没有问题的。如果你的路径当中有多个参数,并且参数都是中文的,你还使用quote,就TMD懵逼了。......
  • 爬虫_057_urllib get请求的quote方法
    目录引子编码集的演变需求知识点重新测试get请求方式的quote方法引子将百度搜索周杰伦的地址栏地址,复制到pycharm当中变成下面的样子:https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6编码集的演变ASCII编码:一个字符一个字节中国:GB2312日本:Shift_JIS韩国:Euc-k......