Django中的choice字段

  应用的场景:

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

书写models创建表模型:

数据的获取和查询:

总结:

"""
1 存choice里面罗列的数字与中文对应关系
print(user_obj.get_gender_display())
只要是choices字段 在获取数字对应的数据 固定语法
get_choices字段名_display() 2 存没有罗列出来的数字
不会报错 还是展示数字
"""

MTV和MVC框架 (了解概念)

MVC(Model View Controller 模型-视图-控制器)

MTV(Model Templates View 模型-模板-视图):

区别:

MVC中的View的目的是「呈现哪一个数据」,而MTV的View的目的是「数据如何呈现」。

   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简介

  AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用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>

  

  

Django与AJAX-choice字段-MTV和MVC模型-sweetalert搭建页面的更多相关文章

  1. django----orm查询优化 MTV与MVC模型 choice参数 ajax serializers

    目录 orm查询优化 only defer select_related 与 prefetch_related MTV 与 MVC 模型 choice参数 Ajax 前端代码 后端代码 前后端传输数据 ...

  2. orm查询优化 MTV和MVC模型 字段的chioces参数 Ajax

    目录 一.ORM查询优化 1. all()查询 2. only()/defer()方法 (1)only()方法 (2)defer()方法 3. select_related()/prefetch_re ...

  3. ORM中choices参数(重要)、MTV于MVC模型、多对多关系三种创建方式

    choices参数(重要) **使用方式

  4. django admin 根据choice字段选择的不同来显示不同的页面

    一.举例 tip/tip.js var react = function () { if (django.jQuery('#id_tiptype').val() == 'content') { dja ...

  5. Django-choices字段值对应关系(性别)-MTV与MVC科普-Ajax发json格式与文件格式数据-contentType格式-Ajax搭配sweetalert实现删除确认弹窗-自定义分页器-批量插入-07

    目录 models 字段补充 choices 参数/字段(用的很多) MTV与MVC模型 科普 Ajax 发送 GET.POST 请求的几种常见方式 用 Ajax 做一个小案例 准备工作 动手用 Aj ...

  6. Django --- 查询优化,ajax

    目录 ORM查询优化 MTV与MVC模型 choices参数 ajax简介 前后端传输数据编码格式 ajax如何传输json格式数据 ajax如何传入文件数据 序列化 ORM查询优化 在使用数据库数据 ...

  7. Django之Ajax传输数据

    MTV与MVC模型 MTV与MVC都是模型,只不过MTV是django自己定义的,具体看一下他们的意思 MTV模型(django) M:模型层(models.py) T:templates文件夹 V: ...

  8. django ajax MTV与MVC 多对多创建方式

    MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...

  9. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

随机推荐

  1. Android中时间戳的详细解释

    Android中时间戳的详细解释: (1).定义: 时间戳就是根据当前系统时间生成的一组随机数字. (2).作用: 作为对数据唯一性的一种判断依据.避免了重复修改数据所带来的错误! (3).应用: ( ...

  2. Python属性和内建属性

    属性property 1. 私有属性添加getter和setter方法 class Money(object): def __init__(self): self.__money = 0 def ge ...

  3. python从命令窗口启动脚本 创建并写入内容到文件示例

    写入到文件示例: #!/usr/bin/env python3 from math import exp, log, sqrt import re from datetime import date, ...

  4. spring boot 环境配置(profile)切换

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  5. 黑马oracle_day01:03.oracle的查询

    01.oracle体系结构 02.oracle的基本操作 03.oracle的查询 04.oracle对象 05.oracle编程 黑马oracle_day01:03.oracle的查询 09scot ...

  6. 1.6判断类型toString.call()

    之前我都是使用typeof,后来发现它的判断有局限,例如(){}obeject.p.toString.call()解决了 obj.toString()的结果和Object.prototype.toSt ...

  7. html5有哪些新特性、移除了那些元素?

    新增的元素: HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加. 拖拽释放(Drag and drop) API 语义化更好的内容标签(header,nav, ...

  8. VC++ DLL 2 静态链接库

    这一篇以VS2013为例子介绍怎样编写一个静态链接库和调用. 1.打开VS2013,新建Visual C++ 的win32项目: 新建后工程分支如下: 添加头文件和源文件: 编写头文件和源文件内容: ...

  9. 关于mysql/apache/nginx的配置文件配置

    2015.5.12 mysql中可以通过函数查看用户列表/查看当前用户以及删除用户,方法百度之,忘了 /etc/php5/fpm/php.ini memory_limit修改之前为128M apach ...

  10. filter的原理(转)

    今天学习了一下javaweb开发中的Filter技术,于是在网上搜了一下相关资料,发现这篇博客写的很不错,于是希望能转载过来以备以后继续学习之用.(原:http://www.cnblogs.com/x ...