Python開發的常用組件

来源:https://www.cnblogs.com/superwinner/archive/2023/01/15/17052473.html
-Advertisement-
Play Games

1. 生成6位數字隨機驗證碼 import random import string def num_code(length=6): """ 生成長度為length的數字隨機驗證碼 :param length: 驗證碼長度 :return: 驗證碼 """ return ''.join(random ...


1. 生成6位數字隨機驗證碼

import random
import string


def num_code(length=6):
    """
    生成長度為length的數字隨機驗證碼
    :param length: 驗證碼長度
    :return: 驗證碼
    """

    return ''.join(random.choice(string.digits) for i in range(0, length))

2.md5加密

import  hashlib


# md5加密
def md5_encrypt(en_str):
    """
    使用md5二次加密生成32位的字元串
    :param en_str: 需要加密的字元串
    :return: 加密後的字元串
    """

    md5 = hashlib.md5()  # 使用MD5加密模式
    md5.update(en_str.encode('utf-8'))  # 將參數字元串傳入
    md5.update(md5.hexdigest().encode('utf-8'))  # md5二次加密
    return md5.hexdigest()

3. 生成唯一token

import uuid
    import  hashlib

    def only_token():
        """
        使用md5加密uuid生成唯一的32位token
        :return: 加密後的字元串
        """
    md5 = hashlib.md5()  # 使用MD5加密模式
    md5.update(str(uuid.uuid1()).encode('utf-8'))
    return md5.hexdigest()

4、發送手機驗證碼

#驗證碼管理表
class AuthCode(models.Model):
    name = models.CharField(max_length=10,default=None, null=True, blank=True,verbose_name='姓名')
    phone = models.CharField(max_length=11, unique=True, verbose_name='手機號')
    code = models.CharField(max_length=6,verbose_name='驗證碼')
    purpose = models.IntegerField(default=0,verbose_name='用途:0->註冊驗證 1->找回密碼 2->其它')
    sendNum = models.IntegerField(default=0,verbose_name='發送次數')
    isCanGet = models.BooleanField(default=0,verbose_name='0->可以獲取,1->不可以獲取')
    recentlySendTime = models.DateTimeField(auto_now_add=True,verbose_name='最近一次發送時間')
    creation_time = models.DateTimeField(auto_now=True, verbose_name='創建時間')

    class Meta:
        verbose_name = '手機驗證碼'
        verbose_name_plural = verbose_name

實現邏輯

import http.client
import urllib
# 使用互億無線
host = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"

# 查看用戶名 登錄用戶中心->驗證碼通知簡訊>產品總覽->API介面信息->APIID
account = "你的用戶名"
# 查看密碼 登錄用戶中心->驗證碼通知簡訊>產品總覽->API介面信息->APIKEY
password = "你的密碼"


def send_sms(text, mobile):
    text = f"您的驗證碼是:{text}。請不要把驗證碼泄露給其他人。"
    params = urllib.parse.urlencode(
        {'account': account, 'password': password, 'content': text, 'mobile': mobile, 'format': 'json'})
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    conn = http.client.HTTPConnection(host, port=80, timeout=30)
    conn.request("POST", sms_send_uri, params, headers)
    response = conn.getresponse()
    response_str = response.read()
    conn.close()
    return response_str


if __name__ == '__main__':
    mobile = "手機號"
    text = '123122'

    print(json.loads(send_sms(text, mobile).decode('utf-8')))

5、生成二維碼

import qrcode
import io

def maker_qrcode(url):
    """
    生成二維碼
    :param url: 需要生成二維碼的url
    :return: 返回圖片位元組流
    """
    image = qrcode.make(url)  # 創建二維碼片

    buffer = io.BytesIO()
    # 將圖片內容丟入容器
    image.save(buffer, 'png')
    # 返回容器內的位元組
    return buffer.getvalue()

或者
from .settings import BASE_DIR

def create_qrcode(name, url):
    """
    生成機器掃碼支付二維碼
    :param name: 圖片名稱
    :param url: 支付路由
    :return:
    """
    img = qrcode.make(url, border=0)  # 創建二維碼片
    save_path = BASE_DIR + '/' + name + '.png'
    print(save_path)
    img.save(save_path)
    return img


6.微信群發

# coding=utf8
import itchat, time

itchat.auto_login(True)

SINCERE_WISH = u'祝%s新年快樂!'

friendList = itchat.get_friends(update=True)[35:]
count = 0

for  index,friend in enumerate(friendList):
    print(index,friend['DisplayName'],friend['NickName'])
    itchat.send(SINCERE_WISH % (friend['DisplayName']
                                or friend['NickName']), friend['UserName'])
    time.sleep(2)
    print('備註名稱',friend['DisplayName'],'昵稱',friend['NickName'],'用戶名',friend['UserName'])

print("----end----")

"""
# 發送文本
itchat.send('Hello, WeChat!')
# 發送圖片
itchat.send_image('my_picture.png')
# 發送視頻
itchat.send_video('my_video.mov')
# 發送文件
itchat.send_file('my_file.zip')

"""

7、微信自動回覆

# -*- coding=utf-8 -*-
import requests
import itchat
import random
#圖靈機器人
#http://www.tuling123.com/member/robot/1380138/center/frame.jhtml?page=0&child=0獲取apikey
KEY = '你的KEY'

def get_response(msg):
    apiUrl = 'http://www.tuling123.com/openapi/api'
    data = {
        'key'    : KEY,
        'info'   : msg,
        'userid' : 'wechat-robot',
    }
    try:
        r = requests.post(apiUrl, data=data).json()
        return r.get('text')
    except:
        return

@itchat.msg_register(itchat.content.TEXT)
def tuling_reply(msg):
    defaultReply = 'I received: ' + msg['Text']
    robots=['','','']
    reply = get_response(msg['Text'])+random.choice(robots)
    return reply or defaultReply

itchat.auto_login(enableCmdQR=False)
itchat.run()

8、提取Django中model中的欄位名變成字典、列表

import re
t = """
    goods_id = models.IntegerField(verbose_name='商品編號')
    label_code = models.CharField(max_length=20, verbose_name='商品標簽')
"""
# 字典
print({k:None for k in re.findall('([a-z_A-Z]+)\s=\s',t)})
# 列表
# print([k for k in re.findall('([a-z_A-Z]+)\s=\s',t)])

輸出
{'goods_id': None, 'lable_code': None}

9、資料庫中給表創建數據

import pymysql

def createData(dataDict,tableName):
    """
    給數據表創建數據
    :param dataDict: 字典
    :param tableName: 表名
    :return:
    """
    #連接資料庫
    conn = pymysql.connect(
        host='192.168.0.188', #資料庫所在地址URL
        user='root', #用戶名
        password='123456', #密碼
        database='名稱', #資料庫名稱
        port=3306,  #埠號
        charset='utf8'
    )
    #拿到查詢游標
    cursor = conn.cursor()
    clos,value = zip(*dataDict.items())
    sql = "INSERT INTO `%s`(%s) VALUES (%s)" % (tableName,
                                                ','.join(clos),
                                                ','.join(['%s'] * len(value))
                                                )
    print(sql)
    cursor.execute(sql, value)
    conn.commit()
    cursor.close()
    conn.close()
    print('Done')

10.捕捉異常

try:
    pass
except 異常類型 as e:
    pass
finally:
    pass


異常類型
Exception  全部異常
AttributeError 試圖訪問一個對象沒有的屬性,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法打開文件
ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典里不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予對象的變數
SyntaxError Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError 傳入對象類型與要求的不符合
UnboundLocalError 試圖訪問一個還未被設置的局部變數,基本上是由於另有一個同名的全局變數,導致你以為正在訪問它
ValueError 傳入一個調用者不期望的值,即使值的類型是正確的

11、獲取當前時間

import datetime

current_time = str(datetime.datetime.now())[:19]
print(current_time)

輸出格式如:2018-10-20 10:01:43
local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
print(local_time)

12、訂單編號

from random import Random
import time

def random_str(randomlength=8):
    str = ''
    chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
    length = len(chars) - 1
    random = Random()
    for i in range(randomlength):
        str+=chars[random.randint(0, length)]
    return str

def order_num():
    """
    生成付款訂單號
    :return:
    """
    local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
    result = local_time + random_str(5)
    return result


print(order_num())

13、mysql自動填寫當前時間

CURRENT_TIMESTAMP

在這裡插入圖片描述

為表添加索引

ALTER table tableName ADD INDEX indexName(columnName)

14、drf動態過濾查詢

# page.py

from rest_framework.pagination import PageNumberPagination


class UserPagination(PageNumberPagination):
    """用戶分頁器"""
    page_size = 10  # 預設的頁面數據數量
    page_query_param = 'page'  # 定製取數據頁碼key
    page_size_query_param = 'page_size'  # 預設取數據頁碼key
    max_page_size = 15   # 數據每頁取值的最大上限



# serializers.py

from rest_framework import serializers

from user.models import UserInfo

class UserSerializers(serializers.ModelSerializer):
    """用戶收貨地址"""

    class Meta:
        model = UserInfo
	    # 所有欄位
        #fields = '__all__'
        fields = ['name', 'code', 'title',  'province', 'city',
                    'quxian', 'address', 'code__gte', 'code__lte']
        # 顯示外鍵
        depth = 2


# views.py
class MachineViews(APIView):
    def get(self, request, *args, **kwargs):
        # 從前端獲取出來的過濾參數,解析成字典傳進filter()函數中
        # 動態過濾,
        kwargs = {}
        # 表中的欄位名
        columns = ['name', 'code', 'title',  'province', 'city',
                    'quxian', 'address', 'code__gte', 'code__lte']
        for k, v in request.query_params.items():
            if k not in columns:
                return Response('參數不對', status=status.HTTP_400_BAD_REQUEST)
			if v:
            	kwargs[k] = v

        users = UserInfo.objects.filter(**kwargs)
        page = UserPagination()
        page_goods_list = page.paginate_queryset(users, self.request, self)
        ser = UserSerializers(page_goods_list, many=True)
        return page.get_paginated_response(ser.data)


15、linux後臺運行python程式

nohup /home/project_venv/user/bin/python3 -u /home/user/user_server.py >> /home/user/user.log 2>&1 &

16、追加外鍵

ALTER TABLE tb_commentPhoto ADD CONSTRAINT FK_comment_phone
FOREIGN KEY tb_goodsComment(id) REFERENCES tb_commentPhoto(comment_id);

17、寫/讀CSV文件,查看是否存在,若存在就從csv中刪除

import csv
import random
import string


def create_invite_code(random_code_pool=None, length=6, num=10, is_append=False):
    """
    創建隨機邀請碼,並寫入txt文件
    :param: random_code_pool 隨機邀請碼
    :param: length 邀請碼長度
    :param: num 邀請碼個數
    :param: is_append True追加,False 覆蓋
    :return:
    """
    if not random_code_pool:
        code_pool = string.ascii_uppercase + string.digits
        random_code_pool = []
        for i in range(num):
            s = ''
            for _ in range(length):
                s += random.choice(code_pool)
            if s and s not in random_code_pool:
                random_code_pool.append(s)

    # 寫入方法。是追加還是覆蓋
    write_method = 'a+' if is_append else 'w'
    # 寫入文件
    with open('./invite_code.csv', write_method, newline='') as f:
        writer = csv.writer(f)
        for rowData in random_code_pool:
            # 按行寫入
            writer.writerow((rowData,))


def check_invite_code(code):
    """
    查看邀請碼是否存在txt文件中,
    若存在就返回True,併在txt文件中刪除
    若不存在就返回False
    :param code:
    :return:
    """![img](https://img2023.cnblogs.com/blog/2959648/202301/2959648-20230114201949035-1110575174.png)
    code_pool = []
    with open('./invite_code.csv', 'r', encoding='utf-8',errors='ignore') as f:
        allFileInfo = csv.reader(f)
        for row in allFileInfo:
            code_pool.append(row[0])

    if code in code_pool:
        # 刪除查詢的code
        code_pool.pop(code_pool.index(code))

        # 重新寫入文件
        create_invite_code(code_pool,is_append=False)
        return True
    return False


if __name__ == '__main__':
    # create_invite_code(length=9,num=100)
    print(check_invite_code('WJ4PSTJG2'))


18、django中從request獲取訪問路徑

print('獲取相對路徑', request.get_full_path())
print('獲取絕對路徑', request.build_absolute_uri())
print(request.build_absolute_uri('?'))
print(request.build_absolute_uri('/')[:-1].strip("/"))
print(request.build_absolute_uri('/').strip("/"))
print(request.build_absolute_uri('/'))
print('----------')
print(request.META['HTTP_HOST'])
print(request.META['PATH_INFO'])
print(request.META['QUERY_STRING'])
iphost = request.META.get('REMOTE_ADDR', '')  # 獲取訪問來源IP


# 輸出如:
獲取相對路徑 /QRcode/?d=1
獲取絕對路徑 http://127.0.0.1:8000/QRcode/?d=1
http://127.0.0.1:8000/QRcode/
http://127.0.0.1:8000
http://127.0.0.1:8000
http://127.0.0.1:8000/
----------
127.0.0.1:8000
/QRcode/
d=1

19、Django收集靜態文件

先在項目根目錄下創建一個static文件夾
然後在settings.py中設置
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
最後執行下麵的命令:
python manage.py collectstatic

20、xadmin插件

https://www.cnblogs.com/lanqie/p/8340215.html

21、uwsgi自動重啟

[uwsgi]
# 使用nginx連接時 使用
socket=0.0.0.0:2019
# 直接作為web伺服器使用
#http=0.0.0.1:8000
# 配置工程目錄
chdir=/home/user
# 配置項目的wsgi目錄。相對於工程目錄
wsgi-file=user/wsgi.py
virtualenv=/home/project_venv/user
#配置進程,線程信息
processes=1
threads=1
enable-threads=True
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log
#啟動uwsgi的用戶名和用戶組
uid=root
gid=root
#uwsgi自動重啟
py-autoreload=1

22、谷歌瀏覽器快捷鍵

瀏覽器緩存

Ctrl+Shift+Del  清除Google瀏覽器緩存的快捷鍵

Ctrl+Shift+R  重新載入當前網頁而不使用緩存內容

23、git克隆分支

git clone -b dev 地址

24、mysql更新語句、新增列、刪除列

update user set name='張三' where id=111
# 刪除
DELETE FROM table_name [WHERE Clause]

# 增加欄位
alter table 表名 add column 列名 類型;
# 刪除欄位
alter table 表名 dropcolumn 列名 ;

25、刪除指定格式的文件

import os
import re


def remove_specified_format_file(file_dir, format_name):
    """
    刪除指定格式的文件
    :param file_dir: 文件根目錄
    :param format_name: 格式
    :return:
    """
    for root, dirs, files in os.walk(file_dir):
        # print(root) #當前目錄路徑
        # print(dirs) #當前路徑下所有子目錄
        # print(files) #當前路徑下所有非目錄子文件
        for file in files:
            if re.match(format_name, file):
                print(os.path.join(root, file))
                os.remove(os.path.join(root, file))


remove_specified_format_file(r'D:\學習\LDC\java', r'\._*')

26、計算文件總數

import os


def file_count(file_dir):
    """

    :param file_dir: 文件根目錄
    :return:
    """
    count = 0
    for root, dirs, files in os.walk(file_dir):
        # print(root) #當前目錄路徑
        # print(dirs) #當前路徑下所有子目錄
        # print(files) #當前路徑下所有非目錄子文件
        count += len(files)
    return count


print(file_count(r'D:\學習\LDC\java\Java學習\newEstore\estore\js'))

27、計算文件夾大小

import os

def file_size(file_dir):
    """
    刪除指定格式的文件
    :param file_dir: 文件根目錄
    :return:
    """
    size = 0
    for root, dirs, files in os.walk(file_dir):
        # print(root) #當前目錄路徑
        # print(dirs) #當前路徑下所有子目錄
        # print(files) #當前路徑下所有非目錄子文件
        for file in files:
            size += os.path.getsize(os.path.join(root, file))
	# M為單位
    return size / 1024 / 1024


file_name = r'D:\學習'
print(file_size(file_name))

28、Django實現jsonp跨域

# html
$.ajax({
                    url: '請求路由',
                    type: 'GET',
                    dataType: 'JSONP',
                    data:{
                      code: 'yes',
                    },
                    jsonp: 'callback',
                    success: function(res) {
                       var selectData = $.parseJSON(res);
                       alert(selectData);
                    },
                    error: function(err) {

                    }
                })

# views.py
def get(self, request, *args, **kwargs):
        code = request.GET.get('code', '')
        # 跨域請求
        callback = request.GET.get('callback', '')
        return HttpResponse("%s('%s')" % (callback, json.dumps({'code': code})), status=status.HTTP_200_OK)

cors解決跨域

https://www.cnblogs.com/wxiaoyu/p/9578848.html

29、微信獲取用戶信息

參考:https://blog.csdn.net/weixin_39735923/article/details/79202563

30、uwsgi初始配置問題

https://blog.csdn.net/weixin_39735923/article/details/79202563

31、django中drf序列化

# 序列化器
class MsgSerializers(serializers.ModelSerializer):
    addtime = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")
    hasread = serializers.CharField(source='get_hasread_display')
    msgtype = serializers.CharField(source='get_msgtype_display')
    class Meta:
        model = MallMsg
        # 可以混合使用
        fields = '__all__'  # '__all__' 所有欄位
        # 資料庫層級控制(序列化鏈表操作)
        # depth = 1  # 外鍵層級


#分頁器
from rest_framework.pagination import PageNumberPagination


class MyLimitOffsetPagination(PageNumberPagination):

    page_size = 3  # 預設的頁面數據數量
    page_query_param = 'page'  # 定製取數據頁碼key ?
    page_size_query_param = 'page_size'  # 預設取數據頁碼key &
    max_page_size = 15  # 數據每頁取值的最大上限

32、第三方庫

安裝openssl
 pip3 install pyOpenSSL

33、requests請求https攜帶CA證書

import OpenSSL
import requests
import urllib3.contrib.pyopenssl

urllib3.contrib.pyopenssl.inject_into_urllib3()

def p12_to_pem(certname, pwd):
    """
    從.p12文件中提取pem
    :param certname:
    :param pwd:
    :return:
    """
    pem_name = certname + ".pem"
    f_pem = open(pem_name, 'wb')
    p12file = certname + ".p12"
    p12 = OpenSSL.crypto.load_pkcs12(open(p12file, 'rb').read(), pwd)
    f_pem.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
    f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
    ca = p12.get_ca_certificates()
    if ca is not None:
        for cert in ca:
            f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
    f_pem.close()
    return pem_name


def post_cert_request(url, data,header, certname, pwd):
    """
    使用證書發起https請求
    :param url:
    :param data:
    :param certname:
    :param pwd:
    :return:
    """
    if (certname != ""):
        cert = p12_to_pem(certname, pwd)
    else:
        cert = None
    r = requests.post(url, header=header, data=data, cert=cert)
    return r

34、django創建緩存命令

python manage.py createcachetable 緩存表名

35、Django 更改超級用戶密碼

在工程文件目錄下敲入:
python manage.py shell

再在python交互界面輸入:
from django.contrib.auth.models import User
user = User.objects.get(username = '用戶名')
user.set_password('密碼')
user.save()

36、restframe使用緩存

https://blog.csdn.net/Odyssues_lee/article/details/80872586

37、資料庫

select * from user  where ISNULL(code)
update user set code='111',info='微信' where ISNULL(code)

38、linux常用命令[[Linux]]

tail -f 日誌名  實時監控日誌
tail -f 80_v10.log

netstat -na|grep 80  查看埠tcp連接數
netstat -na|grep 80 | wc -l 計算埠tcp連接數

ps -ef|grep python  查看有多少python程式在運行

gunzip 2015.csv.gz   # 解壓
unzip 19.zip # 解壓zip
wc -l 2015.csv   # 查看行數
apt install lrzsz  # 安裝
sz 文件名  # 下載文件

查找文件
find / -name 文件名

匹配執行過的以find為開頭的命令
history | grep find

39、xadmin禁止增加、刪除

# models.py
# 用戶管理
class UserManage(models.Model):
    name = models.CharField(max_length=20, verbose_name='用戶名')
    phone = models.CharField(max_length=11, unique=True, verbose_name='手機號')
    code = models.CharField(max_length=11, unique=True, verbose_name='編號')

    user = models.ForeignKey(User, on_delete=models.CASCADE, editable=False, null=True, verbose_name='管理員')

# adminx.py
# 用戶列表
class UserAdmin(object):
    list_display = [ 'code', 'phone', 'name',]
    search_fields = ['code', 'phone']
    list_filter = ['code', 'phone']
    list_editable = ['name']  # 數據即時編輯
    readonly_fields = ['code', 'phone', 'name']  # 只讀欄位,不能編輯
    model_icon = 'fa fa-square'
    model = UserInfo

    def has_delete_permission(self, *args, **kwargs):
    	# 禁止刪除
        if args:
            return True
        return False

	def has_add_permission(self,*args,**kwargs):
		# 禁止增加
        return False

    def save_models(self):
    	# 用戶級別設置
        self.new_obj.user = self.request.user
        flag = self.org_obj is None and 'create' or 'change'
        if flag == 'create':
        	# 對密碼欄位進行加密
            self.new_obj.password = encrypt_oracle(self.new_obj.password)
        elif flag == 'change':
            if 'password' in self.change_message():
                self.new_obj.password = encrypt_oracle(self.new_obj.password)
        else:
        	pass
        super().save_models()

xadmin.site.register(UserInfo, UserAdmin)

40、時間格式字元串相減

import datetime
import time

start = str(datetime.datetime.now())[:19]
time.sleep(60)
end = str(datetime.datetime.now())[:19]
print(start,end)
link_start = datetime.datetime.strptime(start, '%Y-%m-%d %H:%M:%S')
link_end = datetime.datetime.strptime(end, '%Y-%m-%d %H:%M:%S')
link_min = round((link_end - link_start).seconds / 60, 2)
print(link_min,'分鐘')

41、顯示迴圈進度條

參考:https://blog.csdn.net/zejianli/article/details/77915751

from tqdm import tqdm,trange
from time import sleep
text = ""
for char in tqdm(["a", "b", "c", "d"]):
    text = text + char
    sleep(1)


# 方式二
import time


def process_bar(percent, index, total,start_time, start_str='', end_str='', total_length=100):
    # 進度條
    percent_length = int(percent)
    bar = '\r' + start_str + ('\033[1;31;41m \033[0m' * percent_length + '\033[1;37;47m \033[0m' * (
                total_length - percent_length)) + f'  {round(index / total * 100, 2)}%  ' + f' {index}|{end_str}'+ f'   |已進行時間: {round(time.time() - start_time, 2)}秒'

    print(bar, end='', flush=True)


if __name__ == '__main__':
    data_set = [i for i in range(23)]
    i = 0
    start_time = time.time()
    total = len(data_set)
    end_str = '{}'.format(total)
    for data in data_set:
        time.sleep(1)
        i += 1
        process_bar(i * 100 / total, i, total, start_time, start_str='', end_str=end_str, total_length=100)

# 方式三
import sys
import time

d = [i for i in range(100)]
for i in range(len(d)):
    time.sleep(1)
    sys.stdout.write('\r>> Downloading  %.2f%%' % (float(i) / float(len(d)) * 100.0))
sys.stdout.flush()

42、把列表中的字典轉成csv文件

import pandas as pd
lists = [{'a':1,'b':2},{'a':2,'b':3}]
df = pd.DataFrame(lists)
print(df)
df.to_csv('result2.csv')

43、windows添加右鍵新建MarkDown文件

在網上下載Typora軟體安裝後
1、在桌面上新建一個txt文件,輸入以下內容:

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.md\ShellNew]
"NullFile"=""
"FileName"="template.md"

2、另存為,改尾碼為.reg,保存類型為.txt,編碼為Unicode

在這裡插入圖片描述

3、雙擊運行,確定,重啟電腦,此時在桌面右鍵就有了新建md文件

44、redis設置值定時過期

import datetime
import redis

redis_client = redis.Redis(
    host='127.0.0.1',
    port=6379,
    db=0,
    password='123456'
)

def redis_set():
    """
    redis設置值定時過期
    :return:
    """
    global redis_client

    redis_client.set('name','ldc')
    now = datetime.datetime.now()
    # 設置‘name’50秒過期
    expire_time = now + datetime.timedelta(hours=0, minutes=0, seconds=50)
    redis_client.expireat('name', expire_time)


if __name__ == '__main__':
    redis_set()

45、linux根據埠殺進程

import os


def killport(port):
    command = '''kill -9 $(netstat -nlp | grep :''' + str(port) + ''' | awk '{print $7}' | awk -F"/" '{ print $1 }')'''
    os.system(command)


# 開始執行
if __name__ == '__main__':
    port = 4237
    killport(port)

46、監控linux網路流量

iftop -n -N -i eth0


nethogs eth0


vim +/字元串 文件

47、win10添加右鍵打開cmd

通過添加註冊表項實現

win + r 輸入 regedit

找到註冊表位置:HKEY_CLASSES_ROOT\Directory\Background\shell\

右鍵“shel”l,新建“項”,命名為“以管理員身份打開cmd”,

右鍵“以管理員身份打開cmd”,新建“DWORD(32位)值”,命名為"ShowBasedOnVelocityId",值為“639bc8”

右鍵“以管理員身份打開cmd”,新建“項”,命名為“command”

右鍵“command”,點擊“預設”,點擊“修改”,填寫數值為 cmd.exe /s /k pushd “%V”

48、xadmin後臺無法顯示下拉框完整內容

解決方案 在根目錄中找到/static/xadmin/vendor/selectize/selectize.bootstrap3.css
在331行後加入 position: static;

在這裡插入圖片描述

49、xadmin單點登錄

使用中間件實現。

新建一個utils.py文件,存放以下代碼:

    from django.contrib.sessions.models import Session
    from django.db.models import Q
    from django.utils import timezone
    from django.utils.deprecation import MiddlewareMixin


    class XadminMiddleware(MiddlewareMixin):
        def process_request(self, request):
            """xadmin後臺單點登錄"""
            PATH_INFO = request.META.get('PATH_INFO', '')
            if PATH_INFO and 'xadmin' in PATH_INFO:
                request.session.clear_expired()   # 清除過期的key
                session_key = request.session.session_key
                for session in Session.objects.filter(~Q(session_key=session_key), expire_date__gte=timezone.now()):
                    data = session.get_decoded()
                    if data.get('_auth_user_id', None) == str(request.user.id):
                        session.delete()

然後在urls.py中設置:

    urlpatterns = [
    ...
    re_path('^xadmin/', xadmin.site.urls),
    ...
    ]

然後在settings.py中註冊中間件

    MIDDLEWARE = [
    ...

    'utils.xadminauth.XadminMiddleware',
    ...
    ]
	SESSION_COOKIE_AGE = 1209600  # 設置過期時間
    SESSION_SAVE_EVERY_REQUEST = Ture  # 每次請求都更新

【參考】 https://blog.csdn.net/Python_anning

50、Django restful 多個models數據表序列化合併返回(一次請求返回多個序列化器數據)

# 導入第三方包
pip install django-crispy-forms==1.7.2

# 在settings.py中添加應用
INSTALLED_APPS = [
...
'drf_multiple_model',
'rest_framework',
...
]

# 在views.py中使用
    from drf_multiple_model.pagination import MultipleModelLimitOffsetPagination
    from drf_multiple_model.views import ObjectMultipleModelAPIView


    class LimitPagination(MultipleModelLimitOffsetPagination):
        # 多個models數據表聯合查詢,分頁,每頁限制數據10條
        default_limit = 10

    class StudentSerializers(serializers.ModelSerializer):
        """學生表序列化器"""
        # merchant = MerchantSerializers()

        register_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")

        class Meta:
            model = Student
            fields = '__all__'
    class ClassesSerializers(serializers.ModelSerializer):
        """班級表序列化器"""
        # merchant = MerchantSerializers()

        add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")

        class Meta:
            model = Classes
            fields = '__all__'

    class SchoolSerializers(serializers.ModelSerializer):
        """學校表序列化器"""
        # merchant = MerchantSerializers()

        add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")

        class Meta:
            model = School
            fields = '__all__'


    class StudentInfo(ObjectMultipleModelAPIView):
        # 獲取學生信息,班級信息,學校信息

        def get(self, request, *args, **kwargs):
            uid = request.GET.get('uid', '')  # 學生id
            cid = request.GET.get('cid', '')  # 班級id
            sid = request.GET.get('sid', '')  # 學校id

            self.querylist = [
                {'queryset': Student.objects.filter(id=uid).order_by('-id'),
                    'serializer_class':  StudentSerializers, 'label': 'student', },
                {'queryset': Classes.objects.filter(id=cid).order_by('-id'),
                    'serializer_class':  ClassesSerializers, 'label': 'classes', },
                {'queryset': School.objects.filter(id=sid).order_by('-id'),
                    'serializer_class':  SchoolSerializers, 'label': 'school', },
            ]

            return self.list(request, *args, **kwargs)

        pagination_class = LimitPagination

51、 Django序列化器返回外鍵關聯數據

通過 related_name='goods_price’把兩個表關聯起來,當返回Goods的信息時也會返回相應的GoodsPrice信息

    class GoodsPriceSerializers(serializers.ModelSerializer):
        """商品價格表序列化器"""

        class Meta:
            model = GoodsPrice
            fields = ['price']

    class GoodsSerializers(serializers.ModelSerializer):
        """商品表序列化器"""

        goods_price = GoodsPriceSerializers(many=True, read_only=True)

        class Meta:
            model = Goods
            fields = ['title','goods_price']
            depth = 2

    class Goods(models.Model):
        """商品表"""
        title = models.CharField(max_length=50, verbose_name='商品名稱')

        class Meta:
            db_table = 'goods'
            verbose_name = '商品信息表'
            verbose_name_plural = verbose_name

        def __str__(self):
            return self.title

    class GoodsPrice(models.Model):
        """商品價格表,通過外鍵關聯商品信息表"""

        price = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='售價')
        goods = models.ForeignKey(to='Goods', related_name='goods_price', on_delete=models.SET_NULL, blank=True, null=True,verbose_name='商品')

        def __str__(self):
            return str(self.price)

        class Meta:
            managed = True
            db_table = 'goodsPrice'
            verbose_name = '商品售價'
            verbose_name_plural = verbose_name

52、python Django通過User Agent判斷請求來源是微信掃一掃或者是支付寶掃一掃

    class Footest(APIView):
	    def get(self, request, *args, **kwargs):
	        # print(request.META)
	        if 'MicroMessenger' in request.META['HTTP_USER_AGENT']:
	            return Response(data={'msg': '訪問來源是微信'})
	        elif 'AlipayClient' in request.META['HTTP_USER_AGENT']:
	            return Response(data={'msg': '訪問來源是支付寶'})
	        else:
	            return Response(data={'msg': '訪問來源是其他'})

User Agent中文名為用戶代理,簡稱 UA,它是一個特殊字元串頭,使得伺服器能夠識別客戶使用的操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等。

瀏覽器的 UA 字串

標準格式為: 瀏覽器標識 (操作系統標識; 加密等級標識; 瀏覽器語言) 渲染引擎標識 版本信息

獲取user-Agent 之後,
通過識別MicroMessenger或者AlipayClient這樣的關鍵字應該就可以判斷是微信還是支付寶
【參考文章】 https://blog.csdn.net/fly910905/article/details/82498813?utm_source=blogxgwz4

53、xadmin後臺集成’導入‘插件,導入excel文件

效果圖:

在這裡插入圖片描述

1、添加

在虛擬環境根目錄\Lib\site-packages\xadmin\plugins中添加excel.py文件

在這裡插入圖片描述

from xadmin.views import BaseAdminPlugin, ListAdminView
    from django.template import loader
    import xadmin

    class ListExcelImportPlugin(BaseAdminPlugin):
        # 重寫init_request
        import_excel = False
        def init_request(self, *args, **kwargs):
            return self.import_excel

        def block_top_toolbar(self, context, nodes):
            # 這裡 xadmin/excel/model_list.top_toolbar.import.html 是自己寫的html文件
          nodes.append(loader.render_to_string("xadmin/excel/model_list.top_toolbar.import.html"))

    xadmin.site.register_plugin(ListExcelImportPlugin, ListAdminView)

在虛擬環境根目錄\Lib\site-packages\xadmin\plugins__init__.py中

 PLUGINS = (
    ...
        'excel',
    ...
    )

2、添加html文件

在這裡插入圖片描述

在虛擬環境根目錄\Lib\site-packages\xadmin\templates\xadmin\中增加文件夾excel,在文件夾中添加model_list.top_toolbar.import.html文件

 {% load i18n %}
    <div class="btn-group export">
        <a class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown" href="#">
            <i class="icon-share"></i> 導入數據 <span class="caret"></span>
        </a>
        <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
            <li><a data-toggle="modal" data-target="#export-modal-import-excel"><i class="icon-circle-arrow-down"></i> 導入
                Excel</a></li>
        </ul>

        <div id="export-modal-import-excel" class="modal fade">
            <div class="modal-dialog">
                <div class="modal-content">
                    <form method="post" action="" enctype="multipart/form-data">
                        <!--{% csrf_token %}-->
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                            <h4 class="modal-title">導入 Excel</h4>
                        </div>
                        <div class="modal-body">
                            <input type="file" onchange="fileChange(this)" name="excel" id="submit_upload">
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
                            <button class="btn btn-success" type="button" id="submit_upload_b"><i class="icon-share"></i> 導入
                            </button>
                        </div>
                    </form>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dalog -->
        </div><!-- /.modal -->

    </div>

    <script type="text/javascript">
        function fileChange(target) {
            //檢測上傳文件的類型
            var imgName = document.all.submit_upload.value;
            var ext, idx;
            if (imgName == '') {
                document.all.submit_upload_b.disabled = true;
                alert("請選擇需要上傳的 xls 文件!");
                return;
            } else {
                idx = imgName.lastIndexOf(".");
                if (idx != -1) {
                    ext = imgName.substr(idx + 1).toUpperCase();
                    ext = ext.toLowerCase();

                    if (ext != 'xls' && ext != 'xlsx') {
                        document.all.submit_upload_b.disabled = true;
                        alert("只能上傳 .xls 類型的文件!");
                        return;
                    }
                } else {
                    document.all.submit_upload_b.disabled = true;
                    alert("只能上傳 .xls 類型的文件!");
                    return;
                }
            }
        }

        $(document).ready(function () {

            $('#submit_upload_b').click(function () {
                var form_data = new FormData();
                var file_info = $('#submit_upload')[0].files[0];
                form_data.append('file', file_info);
                form_data.append('file_source', $('.breadcrumb li').eq(1).text().trim());
                var url = window.location.protocol + '//' + window.location.host + '/importkdorderno/'
                $.ajax({
                    url: url,
                    type: 'POST',
                    data: form_data,
                    dataType: "json",
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("X-CSRFToken", $.getCookie("csrftoken"))
                    },
                    processData: false,  // tell jquery not to process the data
                    contentType: false, // tell jquery not to set contentType
                    success: function (res) {

                        alert(res.msg);
                        window.location.reload();
                    },
                    error: function (err) {
                    }
                });
            });
        })
    </script>

3、在views.py處理上傳的excel文件

import pandas as pd
    from rest_framework.views import APIView

    class ImportKDOrderNo(APIView):

        def post(self, request, *args, **kwargs):
            file = request.FILES.get('file')
            # read = InMemoryUploadedFile().open()
            data = pd.read_excel(file)  # 使用pandas處理excel文件
    		file_source = request.POST.get('file_source', '')  # 文件來源

            if '訂單號' and '物流單號' not in data:
                return Response(data={'msg': '文件格式有誤,第一行第一列應該為【訂單號】,第一行第二列應該為【物流單號】'})
            ordernos = data['訂單號']
            logistics = data['物流單號']
            for i in range(len(ordernos)):
                print('訂單號', ordernos[i], '物流單號', logistics[i])

            return Response(data={'msg': '上傳成功'})

4、在urls.py中添加訪問路由

from django.urls import path
from 你的應用名稱 import views

app_name = '你的應用名稱'

urlpatterns = [
    # 其他路由
    ...
    # 導入物流單號
    path('importkdorderno/', views.ImportKDOrderNo.as_view(), name='importkdorderno'),
]

54、Django中查找今天進賬金額

views.py

from datetime import datetime
    class CountFee(APIView):
    	def get(self, request, *args, **kwargs):
    		# 獲取當前時間的年月日,然後使用聚合函數添加fee欄位的值
        	year = datetime.now().year
            month = datetime.now().month
            day = datetime.now().day
            count_fees = FeeDetail.objects.filter(addtime__year=year, addtime__month=month, addtime__day=day).aggregate(Sum('fee'))
            all_fee = count_fees['fee__sum'] if count_fees['fee__sum'] else 0
            print(all_fee)
            return Response({'code': 1, 'msg': 'success', 'data': {'all_fee': all_fee}})

55、判斷是什麼系統

import platform
PlATFORM = platform.system()
if PlATFORM == "Linux":
    print('linux')
else:
    print('其他')

56、sql查詢

# 聯合更新
update malluser set master_master_id=3 where master_id in (select a.id from (select id from  malluser where id like '15%')a)
# 統計某欄位重覆數據
SELECT phone, COUNT(*) AS sumCount FROM malluser GROUP BY phone HAVING sumCount > 1;

57、 xadmin後臺刪除數據出現錯誤

get_deleted_objects() takes 3 positional arguments but 5 were given

這是由於Django2.1版本和xadmin不相容導致的

知道虛擬環境\Lib\site-packages\xadmin\plugins\actions.py

修改93行,

deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
            queryset, self.opts, self.user, self.admin_site, using)

改為

deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
            queryset, self.user, self.admin_site)

然後在adminx.py文件中對應的模型類中允許刪除

class MaterialAdmin(object):
    """素材庫分類"""
    list_display = ['id', 'name', 'class_id', 'is_delete', 'addtime']

    def has_delete_permission(self, *args, **kwargs):
        return True

58、xdamin限制用戶點擊

//如果登錄z=xadmin後臺的賬號不是【root】的就不能點擊更新操作
    var master_name = $('#top-nav').find('strong').text();
        master_name =  master_name.substring(4);
    if(master_name != 'root'){
            $(".grid-item a").each(function(index, element) {
                $(this).attr('href','#');
            });
        }

59、獲取公眾號關註url

在微信網頁版,打開公眾號,點擊右上角“…”,在彈框中選擇右下角中間的“查看歷史記錄”,然後在彈框中選擇左上角倒數第一個,“用預設瀏覽器打開”,就可以在打開的瀏覽器中獲取該公眾號的關註url,當把這個url發給好友時,好友點開的就是去關註公眾號的頁面。

60、xadmin後臺用戶操作表許可權

虛擬環境根目錄\Lib\site-packages\xadmin\views\base.py

可以找到:

在這裡插入圖片描述

在項目子應用下的adminx.py中使用

    import xadmin

    from machine.models import Machine


    class MachineAdmin(object):
        list_display = ['code',]  # 顯示的欄位

        search_fields = ['code']  # 搜索的欄位
        list_filter = ['code', 'is_delete'] # 過濾的欄位
        ordering = ('-id',) # 按id降序排序
        list_editable = ['is_delete', ]  # 數據即時編輯
        list_per_page = 30  # 每頁顯示數據數量
        model_icon = 'fa fa-cog fa-spin'  # 左側顯示的小圖標

        def has_delete_permission(self, *args, **kwargs):
            # 刪除許可權
            if self.request.user.is_superuser:  # 管理員才能增加
                return True
            return False

        def has_add_permission(self, *args, **kwargs):
            if self.request.user.is_superuser:  # 管理員才能增加
                return True
            return False

        def has_change_permission(self, *args, **kwargs):
            if self.request.user.is_superuser: # 管理員才能修改
                return True
            return False

        def queryset(self):
            qs = super(MachineAdmin, self).queryset()
            if self.request.user.is_superuser:  # 管理員可以查看所有
                return qs
            else:
                # 登錄用戶只能看到自己修改的數據
                return qs.filter(master_id=self.request.user.last_name)


    xadmin.site.register(MallMachine, MallMachineAdmin)

61、使用nginx部署項目

先在/etc/nginx/sites-available中創建一個配置文件,文件名為test(註意沒有尾碼):

    #設定虛擬主機配置
        server {
            #偵聽80埠
            listen 80;
            listen 443 ssl;
            #定義使用 www.nginx.cn訪問
    		#ssl on;
            server_name  xxx.xxx.com;
            #定義伺服器的預設網站根目錄位置
            root /root/項目名稱;
    		ssl_session_timeout 5m;
            ssl_certificate   /etc/nginx/cert/xxx.pem;
            ssl_certificate_key  /etc/nginx/cert/xxx.key;
            ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            #設定本虛擬主機的訪問日誌
            #access_log  logs/nginx.access.log  main;

            #預設請求
            location / {
                #倒入了uwsgi的配置
                include uwsgi_params;
    		    client_max_body_size	50m;
                #連接uwsgi的超時時間
               # uwsgi_connect_timeout 30;
     	    #設定了uwsig伺服器位置
     	    	uwsgi_pass 127.0.0.1:8002;
            }

            location /static{
          	alias /root/項目名稱/static;
            }
    	location /media {
    	alias /root/項目名稱/media;
    	}

    }

其中xxx.xxx.com表示功能變數名稱.如果沒有https,就使用#把ssl註釋掉就可以了。

然後把test映射到/etc/nginx/sites-enabled

命令

    ln -s /etc/nginx/sites-available/test /etc/nginx/sites-enabled/test

即可
註意:
uwsgi中配置listen=1024時,啟動uwsgi時可能會報錯:

django + uwsgi + nginx 日誌Listen queue size is greater than the system max net.core.somaxconn (128).

解決方法:

修改系統參數

/proc/sys/net/ipv4/tcp_max_syn_backlog  原來2048    改為8192
/proc/sys/net/core/somaxconn	原來128     改為262144

重啟nginx

nginx -s reload

62、xadmin後臺發送郵件找回密碼

在這裡插入圖片描述

輸入你用戶綁定的郵箱

在這裡插入圖片描述

想要發送郵件,需要在settings.py中設置郵件發送器

settings.py最下麵增加

    # ------------------------郵箱配置-----------------------------------------
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' #把要發送的郵件顯示再控制臺上,方便調試
    EMAIL_USE_SSL = True
    EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
    EMAIL_PORT = 465
    EMAIL_HOST_USER = '郵箱賬號' # 帳號
    EMAIL_HOST_PASSWORD = '授權碼'  # 到郵箱里開通
    DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

由於django2與xadmin有些地方不相容,需要修改源碼:

找到虛擬環境根目錄\Lib\site-packages\xadmin\plugins\passwords.py

在passwords.py文件中大概79行,修改為

    return password_reset_confirm(request=request, uidb36=uidb36, token=token,
                                          template_name=self.password_reset_confirm_template,
                                          token_generator=self.password_reset_token_generator,
                                          set_password_form=self.password_reset_set_form,
                                          post_reset_redirect=self.get_admin_url('xadmin_password_reset_complete'),
                                          current_app=self.admin_site.name, extra_context=context).dispatch(request=request,
                                                                                                            uidb64=uidb36,token=token)


找到虛擬環境根目錄Lib\site-packages\django\contrib\auth\views.py

在views.py文件中大概258行,增加:

    # 成功後跳轉路由,根據自己實際來定
    self.success_url = self.request.build_absolute_uri('/') + 'xadmin/'

在這裡插入圖片描述

63、xadmin外鍵下拉框添加過濾


class MallGoodsAdmin(object):
    """商品管理"""
    list_display = ['id', 'show_photo', 'nickname', 'merchant', 'goods_class', 'label',]
    search_fields = ['nickname']
    list_filter = ['goods_class', 'label',]
    model_icon = 'fa fa-bars'
    list_editable = ['goods_class', ]
    #,重寫虛擬環境根目錄下\Lib\site-packages\xadmin\views\edit.py中的formfield_for_dbfield
    def formfield_for_dbfield(self, db_field, **kwargs):
        # 對MallGoodsClass這個表項的下拉框選擇進行過濾
        # MallGoods中有一個goods_class商品分類外鍵MallGoodsClass,過濾掉外鍵MallGoodsClass中
        # master_class為空的值
        if db_field.name == "goods_class":
            kwargs["queryset"] = MallGoodsClass.objects.filter(master_class__isnull=False)
            # 對assigned_recipient這個表項的下拉選擇進行過濾
        	return db_field.formfield(**dict(**kwargs))
        return super().formfield_for_dbfield(db_field, **kwargs)

xadmin.site.register(models.MallGoods, MallGoodsAdmin)

64、xadmin即時編輯器去掉空標簽

在這裡插入圖片描述

虛擬環境根目錄下\Lib\site-packages\xadmin\plugins\editable.py,在大概

129行增加:

    form.fields[fields[0]].empty_label = None

在這裡插入圖片描述

65、用戶增加的小組件,讓其他用戶可見

找到虛擬環境根目錄\Lib\site-packages\xadmin\views\dashboard.py

在548行、554行

在這裡插入圖片描述

改為:

    @filter_hook
        def get_widgets(self):

            if self.widget_customiz:
                portal_pos = UserSettings.objects.filter(
                   key=self.get_portal_key())
                if len(portal_pos):
                    portal_pos = portal_pos[0].value
                    widgets = []

                    if portal_pos:
                        user_widgets = dict([(uw.id, uw) for uw in UserWidget.objects.filter(page_id=self.get_page_id())])
                        for col in portal_pos.split('|'):
                            ws = []
                            for wid in col.split(','):
                                try:
                                    widget = user_widgets.get(int(wid))
                                    if widget:
                                        ws.append(self.get_widget(widget))
                                except Exception as e:
                                    import logging
                                    logging.error(e, exc_info=True)
                            widgets.append(ws)

                    return widgets

            return self.get_init_widget()


66、pip install uwsgi出錯

plugins/python/uwsgi_python.h:2:20: fatal error: Python.h: No such file or directory

首先安裝python3環境

apt install python3-dev

然後再虛擬環境中

pip install uwsgi

66、xadmin後臺載入數據慢,解決方案

list_filter: 過濾器要慎用,不要使用類似id這些數據量大的欄位

    class MallUserAdmin(object):
        """用戶管理"""

        list_display = ['id', 'tp_icon', 'nickname', 'phone', 'level', 'balance', 'province', 'city', 'quxian']  # 顯示欄位
        search_fields = ['id', 'nickname', 'phone']  # 搜索
        list_filter = ['level', 'province', 'city', 'quxian']  # 過濾器
        # list_filter = ['id', 'level', 'province', 'city', 'quxian']  # 如果加id,xadmin載入回來的數據就會很慢,所以不要在過濾器上使用id
        list_per_page = 30  # 預設每頁數量
        model_icon = 'fa fa-users'  # 左側圖標
        ordering = ['-id']  # 排序
        readonly_fields = ['subscribe', 'wx_openid', 'phone']  # 只讀欄位
        is_addbalance = True   # 載入自定義的插件
        relfield_style = 'fk-ajax'  # 其他表如果外鍵到用戶表就做ajax搜索查詢,不一次性載入數據

67 、xadmin導出插件處理,增加導出勾選數據項

常規的導出只有兩個選擇【導出表頭】、【導出全部數據】

在這裡插入圖片描述

現在想要做的是增加一個選擇,即【導出表頭】、【導出全部數據】、【導出勾選數據】,如下圖:

在這裡插入圖片描述

需要修改xadmin源代碼,具體如下

1、載入js文件

找到虛擬環境\Lib\site-packages\xadmin\views\list.py,在607行增加’xadmin.plugin.importexport.js’,如下圖所示

在這裡插入圖片描述

2、修改export.py,後端處理下載文件

找到虛擬環境\Lib\site-packages\xadmin\plugins\export.py

在84行把rows = context[‘results’]修改成如下函數

    # 新增導出所選數據
    # rows = context['results']
    rows = []
    select_across = self.request.GET.get('_select_across', False) == '1'
    selected = self.request.GET.get('_selected_actions', '')
    if self.request.GET.get('selected', 'off') == 'on':
        if not select_across:
            selected_pk = selected.split(',')
            for i in context['results']:
                if str(i['object'].id) in selected_pk:
                    rows.append(i)
        else:
            rows = context['results']
    else:
        rows = context['results']

在這裡插入圖片描述

3、 修改model_list.top_toolbar.exports.html
找到虛擬環境\Lib\site-packages\xadmin\templates\xadmin\blocks\model_list.top_toolbar.exports.html

使用以下代碼覆蓋原文件

    {% load i18n %}
    <div class="btn-group export">
        <a id="export-menu" class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown" href="#">
            <i class="fa fa-share"></i> {% trans "Export" %} <span class="caret"></span>
        </a>
        <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
            {% for et in export_types %}
            <li><a data-toggle="modal" data-target="#export-modal-{{et.type}}"><i class="fa fa-arrow-circle-down">
            </i> {% trans "Export" %} {{et.name}}</a></li>
            {% endfor %}
        </ul>

        {% for et in export_types %}
        <div id="export-modal-{{et.type}}" class="modal fade">
            <div class="modal-dialog">
                <div class="modal-content">
                    <form method="get" action="">

                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&t

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 面向對象編程(OOP) 屬性+方法=類 面向過程 步驟清晰簡單, 第一步做什麼, 第二步做什麼... 適用於處理簡單的問題 面向對象 物以類聚和分類的思想模式 思考解決問題需要做出哪些分類, 然後對這些分類進行單獨思考和研究 最後,將分類下的細節進行了面向過程的研究 面向對象適用於複雜問題, 適合處 ...
  • C++|變數 前言 在C++編程中,需要用到很多種變數 本文將詳談幾種常見變數 如有錯誤,歡迎指出 零、變數格式 定義並賦值 數據類型 變數名=值; 定義 數據類型 變數名; 賦值 變數名=值; 輸入 cin>>變數名; 輸出 cout<<變數名; 一、數字數據類型 如圖所示,雖然 C++ 提供了許 ...
  • 實踐環境 Odoo 14.0-20221212 (Community Edition) web_responsive-14.0.1.2.1.zip https://apps.odoo.com/apps/modules/14.0/web_responsive/ 操作步驟 1、把下載的web_respo ...
  • 1 簡介 Cloud SQL 是GCP上的關係型資料庫,常用的有三種方式來創建: (1) 界面操作 (2) 命令行 gcloud (3) Terraform 在開始之前,可以查看:《初始化一個GCP項目並用gcloud訪問操作》。 2 GCP 操作界面 登陸GCP,選擇SQL,可以創建MySQL、P ...
  • 在上一篇博客中我們有提到一個詞叫做常量,現在就來講講它常量:指的是在程式運行過程中值不會發生改變的量其實我們也有寫過,在這個輸出語句中,這個1就是常量簡單來說程式運行下去,這個1它怎麼樣也不會變成3吧變數:指的是在程式運行過程中值會發生改變的量那麼怎麼來定義一個變數呢我們先來試著定義一個x,值就先為 ...
  • Spring基本介紹02 5.簡單模擬Spring基於XML配置的程式 5.1需求說明 自己寫一個簡單的Spring容器,通過讀取beans.xml,獲取第一個Javabean:Monster的對象,給該對象屬性賦值,放入到容器中,並輸出該對象信息 也就是說,不使用spring原生框架,我們自己簡單 ...
  • 前言 C 語言是一門功能強大的專業化編程語言,深受專業程式員和業餘編程愛好者的喜愛,同時 C 語言也是當今最流行的嵌入式開發語言。大多數嵌入式項目的開發都是用 C 語言來編寫的。 既然 C 語言這麼厲害,那學習 C 語言應該用什麼軟體呢? 推薦使用 Dev-Cpp 在這我推薦初學者使用 Dev-Cp ...
  • Go語言上手(一) 這是我參與「第五屆青訓營 -後端場」筆記創作活動的的第一篇筆記。 先上代碼倉庫: WenTesla/GoLang-Study: 一個學習Go的倉庫 (github.com) 這個倉庫下放下我目前學習GO的所有筆記以及代碼,還未整理,最後會將倉庫進行整理。 基礎語法 一:類型 GO ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...