Django框架:10、Ajax補充說明、多對多三種建立方法、Django內建序列化元件、批次運算元據方法、分頁器思路、form元件

2022-12-20 21:00:31

Django框架

一、Ajax補充說明

1、針對前端回撥函數接受值的說明

主要針對回撥函數args接收到的響應資料

1、後端如何判斷請求發出方式

  • 關鍵詞:is_ajax()
  • 通過request點的方式可以判斷請求是否由Ajax發出
def home(request):
    
    print(request.is_ajax())
    
    return render(request, 'homepage.html')

2、後端檢視層return的返回值不在影響整個頁面

​ 在不使用ajax的時候,檢視層函數return的返回值將直接影響整個頁面,例如使用的’三板斧‘,會直接將返回結果影響到整個頁面,而使用ajax後,返回值將會被前端頁面ajax的回撥函數所接收,不會影響到整個頁面

# 檢視層
def home(request):

    if request.method == 'POST':
        print(request.is_ajax())
        return render(request, 'homepage.html')

    return render(request, 'homepage.html')

# 前端HTML頁面
<body>
    <button id="d1">提交</button>

    <script>
        $('#d1').click(function () {
            $.ajax({
                url: '',
                type: 'POST',
                data: '{"name":"kang"}',
                success: function (args) {
                    console.log(args)

                }
            })
        })
</script>
</body>

3、選擇Ajax做前後端互動時,後端一般都是返回字典資料

後端返回資料

​ 在使用Ajax做互動的時候,後端一般都是返回字典型別的資料,需要將返回的資料轉換成json格式,否則前端將無法接收

def home(request):
    if request.method == 'POST':
        print(request.is_ajax())
        
        data = {'name': 'kangkang'}
        # 需要返回的資料

        import json
        data = json.dumps(data)
        # 將需要返回的資料進行序列化
        
        return HttpResponse(data)

    return render(request, 'homepage.html')

前端如何使用資料

​ 針對發端傳送的Json格式資料,前端是無法直接使用的,需要將json格式資料進行反序列化後才可以使用,反序列化後的資料會成為一個object物件,前端可以直接使用點的方式呼叫資料的值

success: function (args) {
        console.log(args)

        let data = JSON.parse(args)
		  # 將接收的資料進行反序列化
          
        console.log(typeof data)
    	  # 反序列化後的資料是一個object物件

        console.log(data.name)
		  # 物件可以通過點的方式進行取值
    
  }

JsonResponse物件方法

​ 使用JsonResponse方法可以節省後端很多程式碼,而且此方法返回的值,前端不需要進行序列化就可以直接使用

# 匯入JsonResponse物件
from django.http import JsonResponse 


def home(request):
    if request.method == 'POST':
        data = {'name': 'kangkang'}
        # 直接返回
        return JsonResponse(data)

通過修改前端Ajax引數的方法

​ 在前端沒有使用JsonResponse的方法像後端傳值時,前端可以通過設定引數的方式來進行自動反序列化操作

$.ajax({
    url: '',
    type: 'POST',
    data: '{"name":"kang"}',
    dataType:'json',
    # 修改引數
    
    success: function (args) {
        console.log(args)
        console.log(typeof args)
        console.log(args.name)

二、多對多三種建立方式

1、自動建立

​ 自動建立是指,在定義模板階段,在模板內宣告多對多外來鍵欄位,Django會自動識別,並建立出第三張表來儲存多對多的關係

  • 優點:全自動建立,提供了add、remove、set、clear四種操作
  • 缺點:自動建立的第三張表無法建立更多的欄位,拓展性較差
class Book(models.Model):
    title = models.CharField(max_length=32)
    authors = models.ManyToManyField(to='Author')
    
class Author(models.Model):
	name = models.CharField(max_length=32)

2、純手動建立

​ 指,在針對多對多關係時,手動建立第三張表,在第三張表內宣告多對多之間的關係

  • 優點:全由自己建立,拓展性強
  • 缺點:編寫繁瑣,並且不支援add、remove、set、clear以及正反向概念
class Book(models.Model):
    title = models.CharField(max_length=32)
    
class Author(models.Model):
	name = models.CharField(max_length=32)
      
class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')
    others = models.CharField(max_length=32)
    join_time = models.DateField(auto_now_add=True)

3、半自動建立

​ 建立方法類似純手動建立,但是需要在主表中在額外手動定義一個與從表的多對多關係欄位,並且在該欄位後放引數內宣告關聯的從表名和第三張表名以及多對多的關係

  • 優點:第三張表由自己建立,拓展性強,正反向概念清晰
  • 缺點:編寫繁瑣,不支援add、remove、set、clear
class Book(models.Model):
        title = 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', on_delete=models.CASCADE)
        author = models.ForeignKey(to='Author', on_delete=models.CASCADE)
        others = models.CharField(max_length=32)
        join_time = models.DateField(auto_now_add=True)

三、Django內建序列化元件

​ 在實際專案中,針對前後端分離,通常後端試圖函數只需要返回給前端json格式字典,來滿足前端的增刪改查即可,但是在後端ORM操作中,我們一般都是直接獲取到資料物件,這並不滿足向前端傳送資料的需求,所以我們還需要對這些物件進行處理,將物件裡的資料轉換成一鍵值對的形式進行返回

手動處理

from app01 import models
from django.http import JsonResponse


def ab_ser_func(request):
    # 1.查詢所有的書籍物件
    book_queryset = models.Book.objects.all()  # queryset [物件、物件]
    # 2.封裝成大字典返回
    data_dict = {}
    for book_obj in book_queryset:
        temp_dict = {}
        temp_dict['pk'] = book_obj.pk
        temp_dict['title'] = book_obj.title
        temp_dict['price'] = book_obj.price
        temp_dict['info'] = book_obj.info
        data_dict[book_obj.pk] = temp_dict  # {1:{},2:{},3:{},4:{}}
    return JsonResponse(data_dict)

使用序列化元件

1、匯入模組:
	from django.core import serializers
	from app01 import models
    
	def ab_ser_func(request):
		# 獲取全部表物件
       book_queryset = models.Book.objects.all()
    
    	# 生成序列化元件物件,第一個引數是選擇序列化的方式
       res = serializers.serialize('json', book_queryset)
    	
       # 直接將資料進行返回
       return HttpResponse(res)

四、批次運算元據

​ 批次運算元據是指,當前端存取的資料量較為龐大時,通過自己的方法進行處理時會暫用非常長的時間,下面通過程式碼展示

手動生成

​ 這種方式是在不停的向資料庫中插入資料,當資料比較龐大的時候時間非常的滿,10秒500條左右

def temp(request):
    # 設定一個迴圈,當用戶存取時,生成10萬條資料,並插入資料庫
    for i in range(1, 100000):
        book = models.Book01.objects.create(title='number %s book' % i)
		
     # 讀出資料庫中10萬條資料,並傳遞到前端
    obj_list = models.Book01.objects.all()

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

使用內建序列化元件

​ 提前定義一個空列表,然後生成10萬條資料新增到列表中去,再通過內建元件生成,然後展示到前端頁面,5秒10萬條資料

def temp(request):
    # 提交定義一個空列表
    book_obj_list = []
    # 設定一個迴圈,生成10萬條資料
    for i in range(1, 100000):
        book_obj = models.create(title='number %s book' % i)
        # 將生成的物件新增到列表中去
        book_list_obj.append(book_obj)
		
     # 使用內建元件將物件新增到資料庫中
     
     # 讀出資料庫中10萬條資料,並傳遞到前端
    obj_list = models.Book01.objects.all()

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

五、分頁器思路

分頁器主要聽處理邏輯 程式碼最後很簡單 
推導流程
	1.queryset支援切片操作(正數)
	2.研究各個引數之間的數學關係
 		每頁固定展示多少條資料、起始位置、終止位置
 	3.自定義頁碼引數
    	current_page = request.GET.get('page')
 	4.前端展示分頁器樣式
	5.總頁碼數問題
    	divmod方法
 	6.前端頁面頁碼個數渲染問題
    	後端產生 前端渲染

六、自定義分頁器的使用

django自帶分頁器模組但是使用起來很麻煩 所以我們自己封裝了一個

只需要掌握使用方式即可

def ab_pg_func(request):
    book_queryset = models.Books01.objects.all()
    from app01.utils.mypage import Pagination
    current_page = request.GET.get('page')
    page_obj = Pagination(current_page=current_page, all_count=book_queryset.count())
    page_queryset = book_queryset[page_obj.start:page_obj.end]
    return render(request, 'pgPage.html', locals())


{% for book_obj in page_queryset %}
   <p>{{ book_obj.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}

七、form元件

小需求:獲取使用者資料並行送給後端校驗 後端返回不符合校驗規則的提示資訊
    
form元件
	1.自動校驗資料
	2.自動生成標籤
	3.自動展示資訊
    
from django import forms


class MyForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=8)  # username欄位最少三個字元最大八個字元
    age = forms.IntegerField(min_value=0, max_value=200)  # 年齡最小0 最大200
    email = forms.EmailField()  # 必須符合郵箱格式
    
 
校驗資料的功能(初識)
	 form_obj = views.MyForm({'username':'jason','age':18,'email':'123'})
    form_obj.is_valid()  # 1.判斷資料是否全部符合要求
    False  # 只要有一個不符合結果都是False
    form_obj.cleaned_data  # 2.獲取符合校驗條件的資料
    {'username': 'jason', 'age': 18}
    form_obj.errors  # 3.獲取不符合校驗規則的資料及原因
    {'email': ['Enter a valid email address.']}
1.只校驗類中定義好的欄位對應的資料 多傳的根本不做任何操作
2.預設情況下類中定義好的欄位都是必填的