1. 程式人生 > >DAY81-Django框架(十一)

DAY81-Django框架(十一)

一、多對多建立第三張表的三種方式

1.手動建立第三張表

class Book(models.Model):
    # 預設會建立id
    name = models.CharField(max_length=32)
    
class Author(models.Model):
    name = models.CharField(max_length=32)
    
class Book2Author(models.Model):
    id = models.AutoField(primary_key=True)
    book=models.ForeignKey(to='Book',to_field='id')
    author=models.ForeignKey(to='Author',to_field='id')
    #不管是插入和查詢,刪除,都很麻煩(一般不用)

2.通過ManyToMany自動建立第三張表

class Book(models.Model):
    name = models.CharField(max_length=32)
    
# 通過ORM自帶的ManyToManyField自動建立第三張表
class Author(models.Model):
    name = models.CharField(max_length=32)
    books=models.ManyToManyField(to="Book")
#可以通過set,add,clear,remove來對資料增刪改查,操作方便,但是第三張表的欄位就固定了。

3.通過ManyToMany手動建立第三張表,建立關聯關係

class Book(models.Model):
    # 預設會建立id
    name = models.CharField(max_length=32)
    # 中介模型,手動指定第三張中間表是Book2Author
    authors=models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
    #through:指定第三張表
    #through_fields(book,'author'):第一個值是第三張表中與當前表關聯的欄位;
class Author(models.Model):
    name = models.CharField(max_length=32)
    def __str__(self):
        return self.name
class Book2Author(models.Model):
    id = models.AutoField(primary_key=True)
    book=models.ForeignKey(to='Book',to_field='id')
    author=models.ForeignKey(to='Author',to_field='id')
    
#最大的優點是可以在第三張表中新增額外欄位,且比第一種方便

二、AJAX

1.什麼是ajax

​ AJAX(Asynchronous Javascript And XML)翻譯成中文就是“非同步Javascript和XML”。即使用Javascript語言與伺服器進行非同步互動,傳輸的資料為XML。

2.特點

  • 非同步互動:客戶端發出一個請求後,無需等待伺服器響應結束,就可以發出第二個請求。
  • 熱更新:瀏覽器頁面區域性重新整理,這一特點給使用者的感受是在不知不覺中完成請求和響應過程

3.語法

$.ajax({
    //url:指向路由
    url:'/index/',
    //type:傳輸方式
    type:'post',
    //data:往後臺提交的資料
    data:{'name':'lqz','age':18},
    //成功的時候回撥這個函式
    success:function (data) {
        alert(data)
    }
})

三、AJAX案例

案例一

使用者在表單輸入使用者名稱與密碼,通過Ajax提交給伺服器,伺服器驗證後返回響應資訊,客戶端通過響應資訊確定是否登入成功,成功,則跳轉到百度,否則,在頁面上顯示相應的錯誤資訊

模板層ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jquery-3.3.1.js"> </script>
</head>
<body>
<form>
    <input type="text" placeholder="使用者名稱" id="name">
    <input type="password" placeholder="密碼" id="pwd">
    <h1 id="h1"></h1>
</form>
    <button id="btn">登入</button>
</body>
<script>
    $('#btn').click(function () {
        get_data={'name':$('#name').val(),'pwd':$('#pwd').val()}
        $.ajax({
            url:'/ajax1/',
            type:'post',
            data:get_data,
            success:function(data){
                if (data){
                    location.href="https://www.baidu.com";
                }
                else{
                    $('#h1').text('賬號或密碼錯誤')
                }
            }
        })
    })
</script>
</html>

檢視層

from django.shortcuts import render,HttpResponse
from app01 import models
from django.http import JsonResponse
# Create your views here.

def ajax1(request):
    if request.method=='GET':
        return render(request,'ajax.html')

    print(request.POST)
    name = request.POST.get('name')
    pwd = request.POST.get('pwd')
    user_db = models.User.objects.filter(name=name,password=pwd).first()
    if user_db:
        return HttpResponse('1')
    else:
        return HttpResponse()

案例二

在上題的基礎上,以JSON格式資料互動

模板層ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jquery-3.3.1.js"> </script>
</head>
<body>
<form>
    <input type="text" placeholder="使用者名稱" id="name">
    <input type="password" placeholder="密碼" id="pwd">
</form>
    <button id="btn">登入</button>
    <h1 id="h1"></h1>
</body>
<script>
    $('#btn').click(function () {
        var get_data={'name':$('#name').val(),'pwd':$('#pwd').val()}

        $.ajax({
            url:'/ajax1/',
            type:'post',
            //JSON.stringify():轉化為JSON格式
            data:JSON.stringify(get_data),
            //請求的編碼格式:json
            contentType:'application/json',
            //響應的解析方式:json,將後臺給的資料轉為JSON
            dataType:'json',
            success:function(data){
                console.log(data)
                console.log(typeof data)
                //JSON.parse(data):把後臺傳來的資料再轉為JSON格式,注意,如果後臺已經使用JsonResponse傳資料,再用會報錯
                if (data.code){
                    location.href="https://www.baidu.com";
                }
                else{
                    $('#h1').text(data.msg)
                }
            }
        })
    })

</script>
</html>

檢視層

from django.shortcuts import render,HttpResponse
from app01 import models
import json
from django.http import JsonResponse
# Create your views here.

def ajax1(request):
    dic={'code':None,'msg':None}
    if request.method=='GET':
        return render(request,'ajax.html')
    # JSON編碼是在放在body
    res = json.loads(request.body.decode('utf-8'))
    print(res)
    name = res['name']
    pwd = res['pwd']
    user_db = models.User.objects.filter(name=name,password=pwd).first()
    if user_db:
        dic['code']=user_db.name
    else:
        dic['code'] = user_db
        dic['msg']='賬號或密碼錯誤'
        #
    return JsonResponse(dic) #或return HttpResponse(json.dumps(dic))

總結

使用JSON資料互動

​ 前端----->後臺:JSON.stringify()

​ 後臺----->前臺:

​ 1.後臺使用JsonResponse(dic),前臺無需轉換格式

​ 2.後臺使用HttpResponse(json.dumps(dic)),前臺使用dataType:'json' 或者 JSON.parse(data)

案例三

json格式的檔案上傳

模板層

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jquery-3.3.1.js"> </script>
</head>
<body>
<form>
    <input type="text" id="name">
    <input type="file" id="up">
</form>
<button id="btn">上傳</button>
</body>
<script>
    $('#btn').click(function () {
        //上傳檔案,必須用FormData,生產一個formdata物件
        var formdata= new FormData()
        //取出檔案$("#up")[0].files拿到的是檔案列表,取第0個把具體的檔案取出來
        formdata.append('myfiles',$('#up')[0].files[0]);
        formdata.append('name',$('#name').val())
        console.log(formdata)
        $.ajax({
            url:'/files/',
            type:'post',
            data:formdata,
            //processData:true預設,處理data的資料;false,不去處理資料
            processData:false,
            //contentType:指定往後臺傳資料的編碼格式(urlencoded預設,formdata,json);false,不指定編碼
            contentType:false,
            success:function (data) {
                alert(data)
            }
        })
    })
</script>
</html>

檢視層

def files_up(request):
    if request.method=='GET':
        return render(request,'files.html')
    print(request.body)
    print(request.POST)
    print(request.FILES)
    name = request.POST.get('name')
    print(name)
    myfile = request.FILES.get('myfiles')
    with open(myfile.name, 'wb') as f:
        # 迴圈上傳過來的檔案
        for line in myfile:
            # 往空檔案中寫
            f.write(line)
    return HttpResponse('ok')