在pycharm中批量插入表數據、分頁原理、cookie和session介紹、django操作cookie

昨日內容回顧

  • ajax發送json格式數據
'''
	1. urlencoded
	2. form-data
	3. json
'''
 
1. ajax
    $.ajax({
        data: JSON.stringify({'d1':1}),
        contentType:'application/json'
    })
2. api工具
  • ajax發送文件數據
1. form表單
2. ajax
    var myfile = $('#myfile')[0].files[0];
    var myFormData = new FormData();
    myFormData.append('username', '1');
    myFormData.append('password', '2');
    # 添加文件數據
    myFormData.append('myfile', myfile);
    $.ajax({
        data:myFormData,
        
        # 指定兩個參數
        contentType:false,
        processData:false
    })

今日內容概要

  • 批量插入數據
  • 分頁原理和分頁類的使用
  • cookie和session介紹
  • django如何操作cookie

內容詳細

1. 批量插入數據

# 準備數據:
 1.更改配置文件 settings.py:
DATABASES = {
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # }

    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day09',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '123',
        'CHARSET': 'utf8'
    }
}


	2.任一__init__.py文件中寫入:
import pymysql
pymysql.install_as_MySQLdb()


	3.在models.py文件中創建表:
class Book(models.Model):
    title = models.CharField(max_length=32)


	4.完成資料庫遷移:
		makemigrations
		migrate
      
    
# 在tests.py文件中測試:
import os
import sys

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite9.settings")
    import django
    django.setup()
    # 程式碼寫在此處以下

    # 向表中插入十萬條數據
    from app01 import models

    # 方法一:
    # for i in range(100000):  # 效率太低
    #     models.Book.objects.create(title='第%s本書' % i)

    # 方法二:
    # l = []
    # for i in range(100000):
    #     res = models.Book(title='第%s本書' % i)
    #     l.append(res)
    # models.Book.objects.bulk_create(l)

    # 補充:隨機生成固定格式數據模組 faker
    from faker import Faker
    faker = Faker('zh_CN')
    print(faker.name())
    print(faker.email())
    print(faker.phone_number())

image

image

image

2. 分頁原理

總數據100
每頁展示10條

# 1.在 views.py文件寫入:
from app01 import models

def index(request):
    current_page = request.GET.get('page', 1)  # 默認值第1頁
    try:
        current_page = int(current_page)
    except Exception:
        current_page = 1

    all_book_list = models.Book.objects.all()
    total = len(all_book_list)

    # 每頁展示多少條數據
    per_page_num = 10

    # 得到總頁數
    total_page, b = divmod(total, per_page_num)
    if b:
        total_page += 1

    aaa= current_page
    html = ''
    if current_page < 6:
        current_page = 6

    for i in range(current_page-5, current_page+6):
        if aaa == i:
            html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
        else:
            html += '<li><a href="?page=%s">%s</a></li>' % (i, i)


    start = (aaa - 1) * per_page_num
    end = aaa * per_page_num
    book_list = all_book_list[start:end]
    return render(request, 'index.html', locals())


# 2.新建index.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{% for book in book_list %}
    <p>{{ book.title }}</p>
{% endfor %}

<nav aria-label="Page navigation">
  <ul class="pagination">
    <li>
      <a href="#" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>

      {{ html|safe }}

    <li>
      <a href="#" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>
</nav>

</body>
</html>


# 3.在urls.py文件中添加路由:
	url(r'^index/', views.index),
    
# 4.在測試文檔 tests.py文件中添加1000條數據到表中:
l = []
    for i in range(1000):
        res = models.Book(title='第%s本書' % i)
        l.append(res)
    models.Book.objects.bulk_create(l)
    
    
# 別人自行寫好的:
class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=2, pager_count=5):
        """
        封裝分頁相關數據
        :param current_page: 當前頁
        :param all_count:    資料庫中的數據總條數
        :param per_page_num: 每頁顯示的數據條數
        :param pager_count:  最多顯示的頁碼個數
        """
        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)

image

3. cookie和session介紹

1. 很久以前,網站都是靜態的,eg: 新聞類,部落格類
	# 靜態網站不需要登錄
    
2. 隨著發展,後續誕生了支付寶,購物網站...
	# 動態網站需要登錄
    
3. HTTP協議的特點:
	3.1 無狀態
    	誕生了保存用戶數據的cookie,session,token
        
4. cookie介紹
	cookie把數據保存在瀏覽器上,以登錄功能為例,cookie的工作原理:
	"""
	當用戶第一次登錄成功之後,django後端把用戶數據保存在瀏覽器上,瀏覽器會自動把用戶數據提交到django後端,django接收傳過來的用戶資訊,再次做驗證,如果正確,則正常登錄
	"""
    # 用戶名和密碼存在瀏覽器上,不安全
    
5. 為了解決瀏覽器數據不安全問題,誕生了session
	session解決的是安全問題,把數據保存在後端,在django中,session把數據保存在資料庫中(默認保存的),session會把數據保存在django生成的django_session表中
    
	# 工作原理:
		當用戶第一次登錄成功之後,django會自動生成一個隨機字元串,與用戶的真實資訊做一個對應:
			隨機字元串1:用戶資訊1
			隨機字元串2:用戶資訊2
			隨機字元串3:用戶資訊3
            
	django會把隨機字元串返回給瀏覽器,說白了,把隨機字元串保存在cookie里了,當用戶再次進入網站的時候,瀏覽器會自動把隨機字元串提交過來,django會拿著隨機字元串去django_session表中查找對應的資訊,如果有,則說明已經登錄了,如果沒有,說明沒有登錄
    
6. session是基於cookie工作的?
	# 正確
    
7. 如果用戶主動進位了cookie,那麼,session就一定不能用了? 
	# 不是
	7.1 把隨機字元串以參數的形式提交到django
	7.2 把數據放到請求頭中
    
    
# 總結:
	1. cookie的數據保存在瀏覽器
    
	2. session的數據保存在資料庫,session的保存位置是可以更改的:
		2.1 文件
		2.2 資料庫
		2.3 redis
		2.4 memcache
		2.5 消息隊列
        
	3. 專業的消息隊列工具:
		3.1 kafka
		3.2 rabbitmq
		3.3 HTTPsqs
        
	4. session是基於cookie工作

4. django操作cookie

1. obj = HttpResponse()

2. obj = redirect

3. obj = render

# django要想操作cookie,就必須藉助於HttpResponse

# eg:
	登錄功能
    
	01 在views.py文件中寫入:
from django.shortcuts import render, HttpResponse, redirect
from app01 import models


def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        userinfo = models.Book.objects.filter(username=username, password=password).first()
        if userinfo:
            # 保存用戶資訊
            obj = HttpResponse('登錄成功')
            # 保存數據到cookie
            obj.set_cookie('username', userinfo.username, max_age=120)  # max_age 時間 秒 過時數據自動清空
            obj.set_cookie('id', userinfo.id)
            return obj
    return render(request, 'login.html')


# 判斷不登錄不讓訪問
def home(request):
    if request.COOKIES.get('username'):
        return HttpResponse('已經登錄')
    else:
        return redirect('/login/')
    
    
	02 補充表數據 在models.py中:
class Book(models.Model):
    title = models.CharField(max_length=32)
    username = models.CharField(max_length=32, null=True)
    password = models.CharField(max_length=32, null=True)
    
    
	03 添加路由urls.py中:
		url(r'^login/', views.login),
		url(r'^home/', views.home),
        
        
	04 新建 login.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post">
    <p><input type="text" name="username"></p>
    <p><input type="text" name="password"></p>
    <input type="submit" value="提交">
</form>

</body>
</html>

image

image

Tags: