8 Django choices参数 MTV与MVC 创建多对多关系 Ajax介绍

Django

1 choices参数

对于可以将所有的可能值列举完全的字段,一般使用choices参数存储。
例如,性别:男、女、保密。

models.py

class User(models.Model):
	name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 创建对应关系
    gender_choices = (
        (1, '男'),
        (2, '女'),
        (3, '保密'),
    )

    # 字段类型取决于上面对应关系中前者的类型。
    gender = models.IntegerField(choices=gender_choices)
    # gender字段存储数字,对应上面choices参数中对应关系的前者。

models.py

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DemoSite04.settings")

    import django
    django.setup()

    from app01 import models

    models.User.objects.create(name='Ben', age=22, gender=1)
    models.User.objects.create(name='Marry', age=20, gender=2)
    models.User.objects.create(name='Elliot', age=19, gender=3)
    # gender=4不在上面的对应关系中,创建数据成功。
    models.User.objects.create(name='Test', age=20, gender=4)

views.py

user_obj1 = models.User.objects.filter(pk=6).first()
print(user_obj1.gender)  # 3
print(user_obj1.get_gender_display())  # 保密

user_obj2 = models.User.objects.filter(pk=7).first()
print(user_obj2.gender)  # 4
print(user_obj2.get_gender_display())  # 4
  1. 如果gender字段存储的数字在上面的对应关系中,使用get_字段名_display()可以方便地获取对应的值;
  2. 如果gender字段存储的数字不在上面的对应关系中,使用get_字段名_display()得到的还是原数字。
score_choices = (
	('A', '优秀'),
	('B', '良好'),
	('C', '合格'),
	('D', '不合格'),
)

# 字段类型取决于上面对应关系中前者的类型。
score = models.CharField(choices=score_choices, null=True)

2 MTV模型与MVC模型

Django框架号称是MTV模型,本质也是MVC模型。
Vue框架号称是MVVM模型。

MTV模型:Model、Template、View
MVC模型:Model、View、Controller

3 多对多三种创建方式

这里针对的主要是多对多中的第三张关系表。

3.1 全自动

利用ORM自动创建第三张关系表。

class Book(models.Model):
    name = models.CharField(max_length=32)
    authors = models.ManyToManyField(to='Author')

class Author(models.Model):
    name = models.CharField(max_length=32)

优点:
不需要写代码创建第三张关系表,可以使用ORM提供的操作第三张关系表的方法;
缺点:第三张关系表的扩展性差,无法在第三张关系表上添加其它字段。

3.2 纯手动
class Book(models.Model):
	name = models.CharField(max_length=32)
    
class Author(models.Model):
    name = models.CharField(max_length=32)
  
class Book2Author(models.Model):
    book_id = models.ForeignKey(to='Book')
    author_id = models.ForeignKey(to='Author')

优点:第三张关系表可以进行扩展;
缺点:需要写代码创建第三张关系表,无法使用ORM提供的操作第三张关系表的方法,不推荐。

3.3 半自动
class Book(models.Model):
    name = models.CharField(max_length=32)
    authors = models.ManyToManyField(to='Author',
                                     through='Book2Author',
                                     through_fields=('book', 'author')
                                     )
class Author(models.Model):
    name = models.CharField(max_length=32)

class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')

或者

class Book(models.Model):
    name = models.CharField(max_length=32)

class Author(models.Model):
    name = models.CharField(max_length=32)
    books = models.ManyToManyField(to='Book',
                                   through='Book2Author',  # 指定手动创建的第三张关系表
                                   through_fields=('author', 'book')  # 第三张关系表中的外键字段
                                   )

class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')

注意:字段through_fields的外键字段先后顺序
本质:通过第三张关系表查询对应的表,需要用到哪个字段就把哪个字段放前面。
例如,由Book2Author表查询Author表需要字段book,就把字段book放前面。

简化判断方法:把第三张关系表中的当前表对应的关联字段放前面。

半自动:可以使用ORM的正反向查询,但是无法使用add、set、remove、clear这四个方法。
推荐使用半自动。

4 Ajax介绍

4.1 回顾

Ajax核心:异步提交,局部刷新。

  1. 向后端发送请求的方式
操作 请求方式
浏览器地址栏直接输入url并回车 get
点击a标签(href属性) get
提交form表单 get/post
Ajax get/post
  1. 同步交互与异步交互
    同步交互:客户端发送请求后,必须等待服务端响应结束后,才能发送下一个请求;
    异步交互:客户端发送请求后,不需要等待服务端响应,可以直接发送下一个请求。
4.2 什么是Ajax

Asynchronous Javascript And XML,异步的 JavaScript 和 XML,即使用Javascript语言与后端服务器进行异步交互,传输的数据包括 XML,但不限于 XML。

Ajax不是新的编程语言,而是一种使用现有标准的新方法,是基于现有的技术拼接出来的新技术。

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

4.3 Ajax案例
前端页面上有三个input框,在前两个框中输入数字,点击按钮向后端发送Ajax请求。
后端计算出结果,将结果返回给前端,动态展示到第三个input框中。
要求:整个过程中页面不准有刷新动作,也不能在前端进行计算。

urls.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'^add_ajax/', views.add_ajax),
]
4.3.1 HttpResponse对象

如果后端返回含有json数据的HttpResponse对象,默认不会自动进行json格式的转换。

  1. 后端使用json模块对数据进行序列化操作;
  2. 前端的回调函数不会自动对json数据进行反序列化操作,需要设置ajax参数dataType: 'json'

views.py

from django.shortcuts import render, HttpResponse
import json

def add_ajax(request):
    if request.method == 'POST':
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        result = int(i1) + int(i2)

        # 此时返回的任何结果都不会直接作用于浏览器,而是传递给Ajax的回调函数的参数args。
        # return HttpResponse(result)
        res_dict = {
            'code': 100,
            'result': result
        }
        return HttpResponse(json.dumps(res_dict))
    return render(request, 'index.html')

index.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js">script>
head>
<body>
    <div>
        <input type="text" id="i1"> +
        <input type="text" id="i2"> =
        <input type="text" id="i3">
    div>
    <div>
        <button id="btn1">计算button>
    div>
    <script>
        $('#btn1').click(function () {
            // 向后端发送ajax请求。
            $.ajax({
                // 参数1:指定向哪个后端发送ajax请求。
                url: '',  // 默认向当前地址提交ajax请求。
                // 参数2:指定请求方式
                type: 'post',  // 不指定默认是get,小写。
                // 参数3:待发送的数据
                data: {'i1': $('#i1').val(), 'i2': $('#i2').val()},
                // 参数4:自动进行json反序列化操作。
                dataType: 'json',
                // 参数5:回调函数
                // 后端向前端返回结果时自动触发回调函数,参数args用于接收后端返回的结果。
                success: function (args) {
                    $('#i3').val(args['result']);
                    console.log(typeof args);  {#string#}
                }
            })
        })
    script>
body>
html>
4.3.2 JsonResponse对象

如果后端返回JsonResponse对象,回调函数会自动进行反序列化操作。

views.py

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse

def add_ajax(request):
    if request.method == 'POST':
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        result = int(i1) + int(i2)

        res_dict = {
            'code': 100,
            'result': result
        }
        return JsonResponse(res_dict)

    return render(request, 'index.html')

index.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js">script>
head>
<body>
    <div>
        <input type="text" id="i1"> +
        <input type="text" id="i2"> =
        <input type="text" id="i3">
    div>
    <div>
        <button id="btn1">计算button>
    div>
    <script>
        $('#btn1').click(function () {
            $.ajax({
                url: '',
                type: 'post',
                data: {'i1': $('#i1').val(), 'i2': $('#i2').val()},
                success: function (args) {
                    $('#i3').val(args['result']);
                    console.log(typeof args);  {#object#}
                }
            })
        })
    script>
body>
html>

你可能感兴趣的:(Django学习,ajax,python,django,javascript)