Django与AJAX-choice字段-MTV和MVC模型-sweetalert搭建页面

Django中的choice字段

  应用的场景:

    用户信息举列:如用户性别、婚否、学历、工作状态等可以列举出来供选择的信息

书写models创建表模型:

数据的获取和查询:

 

 总结:
"""
      1 存choice里面罗列的数字与中文对应关系
           print(user_obj.get_gender_display())
              只要是choices字段 在获取数字对应的数据 固定语法
              get_choices字段名_display()

      2 存没有罗列出来的数字
          不会报错 还是展示数字
      """

MTV和MVC框架 (了解概念)

   MTV:是Django框架,自己自称的

    M:models模型

    T:templates模板

    V:views视图

   MVC:目前大部分web框架的本质

    M:models

    V:views

    C:controller  控制器(urls)

本质:MTV其实也是MVC

Django与AJAX

  关键理解:异步提交,局部刷新

例如github官网的注册界面:

  注册用户名时,时刻监测用户名是否存在,向后端发送请求,进行动态的校验.

目前所接触到的向后端发送请求方式:

  GET/POST请求

"""
前端中的<a> </a>标签 >>>>>GET请求       
浏览器中输入的url搜索>>>>>GET请求  
from表单  >>>>>>>>>>>>>>>GET/POST请求
AJAX》>>>>>>>>>>>>>>>>>GET/POST请求

"""

 

AJAX简介

  AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

AJAX:有点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

例子:

  页面上有三个input框,在前两个input框中输入数字,点击按钮 发送ajax请求,不刷新页面的情况下,第三个框中自动算出两数之和。

前端向后端发送请求需注意:改成让Django知道走POST请求

 views.py
from django.shortcuts import render,reverse,HttpResponse,redirect

# Create your views here.

def index(request):
    print(request.is_ajax())  # 用来判断当前请求方式是否是ajax请求
    if request.is_ajax():
        if request.method == 'POST':
            # print(request.POST)
            i1 = request.POST.get('i1')
            i2 = request.POST.get('i2')

            # 后端获取的前端数据 都是字符串格式
            res = int(i1) + int(i2)
            return HttpResponse(res)
        return reverse(request,'index.html')
url,py
from django.conf.urls import url
from django.contrib import admin
from app01 import views


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/',views.index),
]
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
     <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.slim.js"></script>
</head>
<body>
<input type="text" id="l1">+<input type="text" id="l2">=<input type="text" id="l3">
<button id="l3">求和</button>
<script> // 绑定点击事件
    $('#l3').on('click',function () {
                {#alert(123)#}
                // 点击按钮 朝后端发送post请求
                $.ajax({
                    url:'',  // 控制发送给谁 不写就是朝当前地址提交
                    type:'post',  // 发送方式是post请求
                    data:{'i1':$('#l1').val(),'l2':$('#l2').val()},  // 发送的数据
                    success:function (data) {  // data形参用来接收异步提交的结果
                        // 将后端计算好的结果 通过DOM操作 渲染到第三个input框中
                        $('#l3').val(data)
                    }
                })
            })
</script>
</body>
</html>
前端书写AJAX部分

运行的结果是:点击求和后向后端发送POST请求,取到结果并展示

contentType前后端传输数据编码格式

常用的数据编码格式有三类:

1.urlencoded  >>>>>  数据格式:name=jack&pwd=123&boby=running
2.formdata    >>>>>>>>>     传文件也支持传普通的键值对:name=jack&pwd=123&boby=running
3.json     >>>>>>>>       josn格式数据(from表单是无法发送Json格式的数据的)

 

  form 表单:默认使用的编码格式是urlencoded,数据格式是:name=jason&pwd=123;发送到后端,

django后端针对urlencoded编码格式的数据会自动解析并放到request.POST中供用户获取。

可以修改为formdata 传文件
      django后端针对只要是符合urlencoded编码格式的数据(name=jason&pwd=123)都会自动解析并放到request.POST中供用户获取

如果是文件 只要你指定的编码是formdata 就会自动解析并放到request.FILES中

 

ajax提交数据:提交的方式默认也是urlencoded
django后端针对不同的编码格式是如何处理的?
1、只要是符合urlencoded编码格式  都会被后端自动获取并解析放到request.POST中
2、如果是符合formdata那么文件会自动被解析放到request.FILES中
3、如果是json格式 后端默认不解析 以二进制的形式就放在request.body你可以自己手动处理即可
ajax发送json格式数据
<script>
    $('#b1').on('click',function () {
        alert(123)
        // 点击按钮 朝后端发送post请求
        $.ajax({
            url:'',  // 控制发送给谁 不写就是朝当前地址提交
            type:'post',  // 发送方式是post请求
            data:JSON.stringify({'username':'jason','password':123}),  // 发送的数据
            contentType:'application/json',  // 告诉后端你这次的数据是json格式

            success:function (data) {  // data形参用来接收异步提交的结果
                alert(data)
                // 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
                $('#i3').val(data)
            }

        })
    // {)
</script>
 要指定传输的数据格式统一

后端验证数据格式:
def index(request):

#验证前后端传输数据的编码格式
    if request.method =='POST':
        print('request.POST',request.POST)
        print('request.FILES',request.FILES)
        jason_str = request.body
        import json
        # 后端 需要手动去request.body中获取json格式数据 自己处理
        res = jason_str.decode('utf-8')
        ral_d = json.loads(res)
        print(ral_d)
        return HttpResponse('OK')
    return render(request,'index.html')

 

总结:前后端在传输数据的时候,一定要保证数据格式和你的编码保持一致性的.

通常情况下,后端针对ajax交互,都是采取字典的形式

基于AJAX传文件:

  关键字formData

传文件:如何获取文件标签存储的问文件对象?固定的语法

  1、先用jQuery查找到存储文件的input标签

  2、将jQuery对象转成原生Javascript对象

  3、利用原生Javascript对象的方法.files[0]获取到标签内部存储的文件对象

{#// ajax传输文件#}
    $('#b1').on('click',function () {
        // ajax传输文件 建议使用内置对象formdata
        var formData = new FormData();  // 既可以传普通的键值对 也可以传文件
        // 添加普通键值
        formData.append('username','jason');
        formData.append('password','123');
        //固定的格式
        formData.append('my_file',$('#d1')[0].files[0]);
        $.ajax({
            url:'',  // 控制发送给谁 不写就是朝当前地址提交
            type:'post',  // 发送方式是post请求
            data:formData, // 发送的数据
            // ajax发送文件需要指定两个额外的参数
            
            processData:false,  // 告诉前端不要处理数据
            contentType:false,  // 不适用任何编码,因为formdata对象自身自带编码 django后端也能够识别formdata对象
            success:function (data) {  // data形参用来接收异步提交的结果
                alert(data)
                // 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
                $('#i3').val(data)
            }

        })

 

注意固定的格式及一些参数的使用

序列化组件

  Django内置的serializers

  简单的解释就是前端想拿到由ORM得到数据库中里面得一个个用户对象,为了简便操作,

后端直接将实例化出来的数据对象直接发送给客户端,这时候就需要用到序列化模块。

主要是考虑Json序列化字典的数据格式,传输的数据类型比较多,也可以以K:V键值对的形式取值。

from django.core import serializers  # django自带的一个小型的序列化工具
def reg(request):
    user_list = models.User.objects.all()
  原来的数据传输:
# 将所有的数据都组织成一个符合json的一个个的字典 # user_l = [] # for user_obj in user_list: # user_l.append( # json.dumps({'username':user_obj.username, # 'age':user_obj.age, # 'gender':user_obj.get_gender_display() # }) # ) res = serializers.serialize('json',user_list) # return render(request,'index.html',locals())

 利用在这json在线格式转换工具:

 

 AJAX结合sweetalert插件的应用(动态弹框)

  实现以下的动态弹框提示,点击下载Bootstrap-sweetalert项目。需要导入的插件,统一放入static文件中配置到settings.py文件下.

 

views.py

from django.http import JsonResponse
import time
def userlist(request):
    if request.is_ajax():
        time.sleep(3)
        """
        一般情况下 针对ajax请求 后端通常都是返回一个字典
        """
        back_dic = {'code':100,'msg':''}
        # 直接获取用户想删除的数据的id值
        delete_id = request.POST.get('delete_id')
        # 直接利用queryset方法 批量删除
        models.User.objects.filter(pk=delete_id).delete()
        # 要给前端ajax返回一个消息(字典)
        back_dic['msg'] = '真的删除了!'
        return JsonResponse(back_dic)


    user_list = models.User.objects.all()
    return render(request,'userlist.html',locals())

userlist.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
    <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    <script src="{% static 'dist/sweetalert.min.js' %}"></script>

    <style>
        div.sweet-alert h2{
            padding-top: 10px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h2 class="text-center">数据展示</h2>
            <table class="table-striped table table-hover table-bordered">
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>主键</th>
                        <th>用户名</th>
                        <th>年龄</th>
                        <th>性别</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user in user_list %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ user.pk }}</td>
                            <td>{{ user.username }}</td>
                            <td>{{ user.age }}</td>
                            <td>{{ user.get_gender_display }}</td>
                            <td>
                                <button class="btn btn-primary btn-sm">编辑</button>
                                <button class="btn btn-danger btn-sm del" user_id="{{ user.pk }}">删除</button>
                            </td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
<script>
    $('.del').click(function () {
        // 获取当前标签对象
        var $btnEle = $(this);

        swal({
          title: "你确定要删吗?",
          text: "你要是删了,你就准备跑路吧!",
          type: "warning",
          showCancelButton: true,
          confirmButtonClass: "btn-danger",
          confirmButtonText: "是的,老子就要删!",
          cancelButtonText: "算了,算了!",
          closeOnConfirm: false,
          showLoaderOnConfirm: true
        },
        function(){
            // 朝后端发送ajax请求
            $.ajax({
                url:'',
                type:'post',
                data:{'delete_id':$btnEle.attr('user_id')},
                success:function (data) {  // 后端发字典过来 前端不需要你手动转 会自动帮你转换成js自定义对象
                    if (data.code == 100){
                        {#window.location.href = '';  // 不写就是条到当前页面#}
                        // 通过DOM操作 实时改变页面
                        // 将被点击的删除按钮所在的那一行直接从DOM树中删掉
                        $btnEle.parent().parent().remove();
                        swal("删掉了!", "赶紧回去收拾行李吧,准备跑路!", "success");
                    }else{
                        swal('发生了未知的错误','估计是有bug了','info')
                    }
                }
            });

        });
    })
</script>

</body>
</html>

效果如下:

 

 

自定义分页器

直接拷贝代码然后导入使用即可:

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数

        用法:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        获取数据用page_data而不再使用原始的queryset
        获取前端分页样式用page_obj.page_html
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

 

导入使用
from app01.utils.mypage import Pagination
def book(request):
    # 使用封装好的自定义分页器
    book_list = models.Book.objects.all()
    current_page = request.GET.get("page",1)
    all_count = book_list.count()
    page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
    page_queryset = book_list[page_obj.start:page_obj.end]

    return render(request,'booklist.html',locals())

 

booklist.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
    <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    <script src="{% static 'dist/sweetalert.min.js' %}"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book in page_queryset %}
            <p>{{ book.title }}</p>
            {% endfor %}
            {{ page_obj.page_html|safe }}
        </div>
    </div>
</div>
</body>
</html>

 

 

 

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

转载于:https://www.cnblogs.com/Gaimo/p/11575462.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建一个django-vue-admin项目,你可以按照以下步骤进行操作: 1. 首先,创建一个Django项目,并安装所需的依赖。在设置文件中,确保你的TEMPLATES配置中包含了以下内容:'BACKEND': 'django.template.backends.django.DjangoTemplates'。 2. 接下来,配置Django的模板上下文处理器。在设置文件中,确保你的TEMPLATES配置中包含了以下内容:'django.contrib.auth.context_processors.auth'和'django.template.context_processors.request'。 3. 然后,安装django-vue-admin库。你可以使用pip安装它:pip install django-vue-admin。 4. 在你的Django项目中创建一个新的应用程序。你可以使用以下命令创建一个名为"admin"的应用程序:python manage.py startapp admin。 5. 在你的项目设置文件中注册新创建的应用程序。将'app名'admin'添加到你的INSTALLED_APPS配置中。 6. 在admin应用程序的目录中创建一个名为"templates"的文件夹,并在其中创建一个名为"admin"的子文件夹。 7. 在"admin"文件夹中创建一个名为"base.html"的模板文件,该文件将作为你的项目的基础模板。 8. 在"base.html"模板文件中,使用Vue.js编写前端代码,以实现你希望在项目中看到的功能和样式。 9. 在你的admin应用程序的视图中,定义需要的后端逻辑和模型操作。 10. 最后,运行你的Django服务器并访问项目的URL,以查看django-vue-admin项目的效果。 请按照以上步骤进行操作,你就可以成功地搭建一个django-vue-admin项目了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Django+Vue环境搭建](https://blog.csdn.net/WeirdoGiraffe/article/details/124863602)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值