Django之批量插入數據、自定義分頁器、多對多表關系的三種創建方式


Django之批量插入數據、自定義分頁器、多對多表關系的三種創建方式

批量插入數據

用bulk_create

def index(request):
    # 1、往書籍表中插入數據1000條
    # for i in range(1000):   # 這種插入方式,效率極低
    #     models.Book.objects.create(title='第%s本書'%i)
    
    book_list = []
    for i in range(100000):  # 插100000條,速度還是很快
        book_list.append(models.Book(title='第%s本書'%i'))
    models.Book.objects.bulk_create(book_list)   # 批量插入數據
    
    # 2將剛剛插入的數據查詢出來展示到前端
    book_queryset = models.Book.objects.all()
    return render(request, 'index.html', locals())

自定義分頁器

推導思路

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.
from django.core.exceptions import  ValidationError
def index(request):
    # 1.往書籍表中插入數據 1000
    # for i in range(1000):  # 這種插入方式 效率極低
    #     models.Book.objects.create(title='第%s本書'%i)
    # book_list = []
    # for i in range(100000):
    #     book_list.append(models.Book(title='第%s本書'%i))
    # models.Book.objects.bulk_create(book_list)  # 批量插入數據
    # 2.將剛剛插入的數據查詢出來展示到前端

    # 1.獲取用戶想要訪問的頁碼數
    current_page = request.GET.get('page',1)  # 如果沒有page參數 默認就展示第一頁
    # 轉成整型
    current_page = int(current_page)
    # 2.每頁展示10條數據
    per_page_num = 10

    # 3.定義起始位置和終止位置
    start_page = (current_page - 1) * per_page_num
    end_page = current_page * per_page_num

    # 4.統計數據的總條數
    book_queryset = models.Book.objects.all()
    all_count = book_queryset.count()

    # 5.求數據到底需要多少頁才能展示完
    page_num, more = divmod(all_count,per_page_num)  # divmod(100,10)
    if more:
        page_num += 1
    # page_num就覺得了 需要多少個頁碼
    page_html = ''
    xxx = current_page  # xxx就是用戶點擊的數字
    if current_page < 6:
         current_page = 6
    for i in range(current_page-5,current_page+6):
        if xxx == i:
            page_html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)
        else:
            page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i)

    book_queryset = book_queryset[start_page:end_page]
    return render(request,'index.html',locals())

"""
per_page_num = 10
current_page                   start_page                      end_page
    1                              0                                10
    2                              10                               20
    3                              20                               30 
    4                              30                               40

per_page_num = 5
current_page                   start_page                      end_page
    1                              0                                5
    2                              5                                10
    3                              10                               15 
    4                              15                               20

start_page = (current_page - 1) * per_page_num
end_page = current_page * per_page_num
"""

這個知識點的重點在於推導思路,自定義分頁器的使用:新建一個py文件將以下代碼直接拷貝過去

# 分頁器組件

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=10, 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)

后端使用views.py

from app01.utils.mypage import Pagination
# 使用封裝好的分頁器代碼
def login(request):
    book_queryset = models.Book.objects.all()  # 先得到書的所有數據對象
    # 獲取用戶想要訪問的頁碼數,沒有page參數,就默認展示第一頁
    current_page = request.GET.get('page',1)   # 獲取當前頁
    all_count = book_queryset.count()   # 獲取數據的總條數
    # 1.實例化產生對象
    page_obj = Pagination(current_page=current_page,all_count=all_count)
    # 2.對真實數據進行切片操作
    page_queryset = book_queryset[page_obj.start:page_obj.end]
    return render(request,'login.html',locals())

前端展示數據login.html

<body>

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

</body>

創建多對多表關系的三種方式

1、全自動(推薦使用**)

好處在於django orm會自動幫你創建第三張關系表

但是它只會幫你創建兩個表的關系字段,不會再額外添加字段。

該方法雖然方便,但是第三張表的擴展性較差,無法隨意的添加額外的字段

class Book(models.Model):
    ...
    authors = models.ManyToManyField(to='Author')

class Author(models.Model):
    ...
    

2、純手動(不推薦)

好處在於第三張關系表可以任意的添加額外的字段。

不足之處在於orm查詢的時候,很多方法都不支持,查詢的時候非常麻煩

class Book(models.Model):
	...  # 創建書籍表的字段的代碼
                
class Author(models.Models):
	...
            
class Book_Author(models.Model):
	book_id = models.ForeignKey(to='Book')
	author_id = models.ForeignKey(to='Author')
	create_time = models.DateField(auto_now_add=True)
	...

3、半自動(最推薦使用)

手動建表,但是會告訴orm第三張表是你自己建的,orm只需要給我提供方便的查詢方法。

這種方法雖然可以使用orm查詢方法,但是不支持使用:add()、set()、remove()、clear()。

注意:

1.半自動 一定要加兩個額外的參數
through='Book_Author', through_fields=('book','author')
2.后面字段的順序
由第三張表通過哪個字段查詢單表 就把哪個字段放前面

class Book(models.Model):
    ...
    authors = models.ManyToManyField(to='Author', through='Book_Author', through_fields=('book', 'author'))  #  由第三張表通過哪個字段查詢單表 就把哪個字段放前面
    
class Author(models.Model):
	...
	books = models.ManyToManyField(to='Book', through='Book_Author', through_fields=('author', 'book'))

class Book_Author(models.Model):
	book = models.ForeignKey(to='Book')
	author = models.ForeignKey(to='Author')
	create_time = models.DateField(auto_now_add=True)
	...
  

在設計項目的時候,一定要給自己留后路,防止后續的迭代更新


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM