1. 程式人生 > 實用技巧 >小知識點總結

小知識點總結


...mapState

  事實上...mapState並不是mapState的擴充套件,而是...物件展開符的擴充套件.當然如果你把他用在這裡會發現他能使得程式碼看起來變得,更加符合常規邏輯了,為什麼這麼說,你等下就會知道了.

  首先,來回顧一下...物件展開符在陣列中的表現,這在ES6語法學習分類裡有相關說明,如果有興趣可以關注我的ES6分類中的文章.

    let arr = [1,2,3]
    console.log(...arr) //1,2,3
    
    在該元件的js中,通過this.xxx即可使用 mapState 對映的內容
————————————————
原文連結:https://blog.csdn.net/dkr380205984/article/details/82185740
前端中的join
join() 方法用於把陣列中的所有元素放入一個字串。作用是將陣列轉換為字串,其作用和toString()相同。
  元素是通過指定的分隔符進行分隔的。
例如:

  var asp=['H','ell','o'];
    a=asp.join('#');  #:表示以什麼符號連結 a=asp.join('');  輸出:Hello
    console.log(a);  輸出:H#ell#o
流程判斷語句
if (...) {
    ...
} else if {
    ...
} else {
    ...
}

前端程式碼規範命令

npm run lint # 相當於後端的格式化. 自動更正錯誤的格式
宣告週期
// mounted 在完成模板渲染後執行的方法,比如
mounted() {
      this.seteditor();
      this.editor.txt.html(this.value);
    },
python 獲取時分秒
import os
import time
# 格式化成2016-03-20 11:45:39形式
monthTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
python時間區間比較
from dateutil.parser import parse
NOW = datetime.datetime.now()
gt = parse("8:00:00")
lt = parse("20:00:00")
print(gt,type(gt))
print(lt,type(lt))
print(gt<NOW<lt)
js中的倒計時
this.$axios.get(`${this.$settings.HOST}/user/sms/${this.mobile}/`)
          .then(response => {
            console.log(response.data);
            this.is_send_sms = true;
            let interval_time = 10;
            let timer = setInterval(() => {
              if (interval_time <= 1) {
                // 停止倒計時,允許使用者點擊發送簡訊
                clearInterval(timer);
                this.is_send_sms = false; // 設定簡訊傳送段的間隔狀態為false,允許點擊發送簡訊
                this.sms_text = "點擊發送簡訊";
              } else {
                interval_time--;
                this.sms_text = `${interval_time}秒後重新點擊發送`;
              }
            }, 1000) // 倒計時元件1000毫秒執行一次, 也就是1秒執行一次.
          })

element中的Message函式

import { Message } from 'element-ui';

export function showMessage(msg, type = 'info', center = true) {
  Message({ message: msg, type: type, center });
}

export function showErrorMessage(error = '錯誤', type = 'error') {
  showMessage('在獲取系統下拉選單過程中發生錯誤,詳見開發者工具中內容', type);
  console.log('獲取系統下拉選單過程中發生錯誤:', error);
}

js獲取秒級時間戳
var startTime = Date.parse(new Date()) / 1000; // 獲取秒級時間戳
var endTime = Date.parse(new Date()) / 1000;
js中的json
JSON.stringify(this.file_ls); // 序列化
JSON.parse(this.file_path) // 反序列化
el中的選擇時間範圍元件
<el-col :span="7">
  <el-date-picker
    v-model="timeValue"
    :picker-options="pickerOptions"
    type="daterange"
    size="small"
    align="right"
    unlink-panels
    range-separator="至"
    start-placeholder="開始日期"
    end-placeholder="結束日期"
    value-format="yyyy-MM-dd HH:mm:SS"/>  // 格式化時間; 使用者選擇後會將值傳遞給timeValue,這個變數
</el-col>
跨元件呼叫方法

frontend\src\views\home\details\index.vue

前端去重
var ckls = new Set(this.checkList); // 把列表轉換成集合,去重
this.checkList = Array.from(ckls);  // 再把集合轉換成陣列
js合併物件
var assignObj = Object.assign(params, this.params);
ORM那些事
屬性 SQL元
__exact like 'aaa'
__iexact 忽略大小寫 ilike 'aaa
__contains 包含 like '%aaa%'
__icontains 包含 忽略大小寫 ilike '%aaa%'
__gt 大於
__gte 大於等於
__lt 小於
__lte 小於等於
__in 存在於一個list範圍內
__startswith 以...開頭
__istartswith 以...開頭 忽略大小寫
__endswith 以...結尾
__iendswith 以...結尾,忽略大小寫
__range 在...範圍內
__year 日期欄位的年份
__month 日期欄位的月份
__day 日期欄位的日
__isnull True/False
__isnull True 與 __exact=None的區別

物件過濾那些事

filter
exclude 
	Business.objects.exclude(instanceid__in=instan_ls) # 排除在某個範圍的內容
put請求
# url,命名路由的名稱要跟資料庫欄位相對應
urlpatterns = format_suffix_patterns([
    url(r'dealt/(?P<dealt_identity>.*?)$',DealtModelViewSet.as_view({'get':'list','put':'update','post':'create'}))
])

# 檢視
class DealtModelViewSet(ModelViewSet):
    ...
	def update(self, request, *args, **kwargs):
        self.lookup_field = 'dealt_identity' # 命名路由中的內容就是pk,指定pk對應資料庫的key是啥
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response(apiResult('success', 2000, data=serializer.data))
    
# 序列化器
# 此處需要注意: 將資料庫必填欄位,在此重新宣告為非必填,否則會丟擲必填錯誤
# self.initial_data是源資料, 而validated_data是校驗後的資料
class WaltDealtSerializer(serializers.ModelSerializer):
        implement_peo__username = serializers.SerializerMethodField(required=False)
		...
	    def update(self, instance, validated_data):
        dealt_obj = Dealt.objects.filter(dealt_identity=self.initial_data.get('dealt_identity', None)).first()
        implement_peo__username = self.initial_data.get('implement_peo__username', None)
        user = UserProfile.objects.filter(username=implement_peo__username).first()
        dealt_obj.implement_peo = user
        dealt_obj.save()
        return dealt_obj

js獲取當前時間年月日時分秒
getNowTime() {
  var dateTime = new Date();
  var year = '';
  var month = '';
  var date = '';
  var hour = '';
  var minute = '';
  var second = '';
  var milliSeconds = '';
  year = dateTime.getFullYear();
  month = dateTime.getMonth() + 1;
  date = dateTime.getDate();
  hour = dateTime.getHours() < 10 ? '0' + dateTime.getHours() : dateTime.getHours();
  minute = dateTime.getMinutes() < 10 ? '0' + dateTime.getMinutes() : dateTime.getMinutes();
  second = dateTime.getSeconds() < 10 ? '0' + dateTime.getSeconds() : dateTime.getSeconds();
  milliSeconds = dateTime.getMilliseconds();
  var currentTime = year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second + '.' + milliSeconds;
  return currentTime;
}
js捕獲異常
try {
  //執行程式碼
} catch(err) {
  //處理錯誤
}
上傳檔案

即刻上傳

<el-col :offset="1" :span="1">
  附件
</el-col>
<el-col :span="4">
  <el-upload
    :on-success="successUp"
    :headers="{'Authorization':token}"
    :file-list="fileList"
    class="upload-demo"
    action="http://127.0.0.1:8000/wait-dealt/files/">
    <el-button size="small" type="primary">點選上傳</el-button>
    <div slot="tip" class="el-upload__tip" style="color: red">多個檔案,請壓縮後上傳,且不超過5M</div>
  </el-upload>
</el-col>

redis 刪除某個鍵的值
redis_conn.delete('identity_%s' % yesterday_identity)
drf 序列化和反序列化那些事

序列化最後走的是序列化器中定義的方法

反序列化時, 它會先走資料庫, 根據資料庫欄位名和它的型別, 對照著反序列化, 所以你提交的欄位名字需要跟資料庫中的名字相對應, 這樣才能在校驗後的資料中獲取到, 否則只能在元資料(self.initial_data) 獲取

# 序列化器
def create(self,validated_data):
    name = validated_data.get('name') # 這裡獲取的都是反序列化後的內容, 也就是跟資料庫欄位想對應的內容,並且也已經將型別反序列化好了
    name = self.initial_data.get('name') # 這裡獲取的都是沒有經過反序列化校驗的內容,一般都是字串
apschedule倒計時

[^1] interval方式的觸發器演示

import datetime
import time
from apscheduler.schedulers.blocking import BlockingScheduler

def func():
    ts = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('do func time :', ts)

def func2():
    ts = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('do func2 time:', ts)
    time.sleep(2)

def dojob():
    scheduler = BlockingScheduler()
    # 新增任務,時間間隔2S
    scheduler.add_job(func, 'interval', seconds=2, id='test_job1')
    scheduler.add_job(func2, 'interval', seconds=3, id='test_job2')
    os.name是獲取系統的型別, windows返回nt;linux返回posix;
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
    scheduler.start()

dojob()

三種觸發器:

# 未顯式指定,那麼則立即執行

interval: 週期觸發任務
sched.add_job(job_function, 'interval', hours=2) # 每2小時觸發
# 週期觸發的時間範圍在2010-10-10 9:30 至 2014-06-15 11:00
sched.add_job(job_function, 'interval', hours=2, start_date='2010-10-10 09:30:00', end_date='2014-06-15 11:00:00')


date 在指定時間點觸發任務
sched.add_job(my_job, 'date', run_date=date(2009, 11, 6), args=['text'])
sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text'])


cron 則按固定的時間間隔觸發



# 也可以通過scheduled_job()裝飾器實現

seconds: 秒 ; 此外還有hour(小時) ; minute(分鐘)

MemoryJobStore # 儲存器

Avue那些事

傳遞到元件中的內容需要進行json反序列化

JSON.parse(xxx)

python 字串保留3位數字
str(hou_title).zfill(3)

js 判斷陣列中是否有某個值

Arry.includes('Admin');

模型中的ForeignKey欄位,新增資料,要給個例項物件

JS 正計時
basisModel.getTask()
    .then(res => {
    for (var index in res.data.results) {
        res.data.results[index].num = index;
    }
    this.tableData = res.data.results;
    // parseInt 字串轉數字,不是在原值上修改
    setInterval(() => {
        for (var dex in this.tableData) {
            var ls = this.tableData[dex].trigger_time.split(':');
            var [hour, minutes, seconds] = ls;
            hour = parseInt(hour);
            minutes = parseInt(minutes);
            seconds = parseInt(seconds);
            seconds += 1;
            if (seconds >= 59) {
                seconds = 0;
                if (minutes >= 59) {
                    minutes = 0;
                    hour += 1;
                } else {
                    minutes += 1;
                }
            }
            var hour1 = hour.toString();
            var minutes1 = minutes.toString();
            var seconds1 = seconds.toString();
            if (hour1.length === 1) {
                hour1 = '0' + hour1;
            }
            if (minutes1.length === 1) {
                minutes1 = '0' + minutes1;
            }
            if (seconds1.length === 1) {
                seconds1 = '0' + seconds1;
            }
            this.tableData[dex].trigger_time = hour1 + ':' + minutes1 + ':' + seconds1;
        }
    }, 1000);
})
    .catch(() => {
    this.$message.error('獲取資料時出錯,請聯絡管理員解決');
});

後端

# 資料該物件的欄位是 DateTimeField
time_obj = obj.trigger_time
timing_seconds = datetime.now() - time_obj
seconds = timing_seconds.seconds
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
consume_time ="%02d:%02d:%02d" % (h, m, s)
return consume_time
Vue中的computed屬性
轉自: https://www.cnblogs.com/gunelark/p/8492468.html
    computed用來監控自己定義的變數,該變數不在data裡面宣告,直接在computed裡面定義,然後就可以在頁面上進行雙向資料繫結展示出結果或者用作其他處理;
    computed比較適合對多個變數或者物件進行處理後返回一個結果值,也就是數多個變數中的某一個值發生了變化則我們監控的這個值也就會發生變化,舉例:購物車裡面的商品列表和總金額之間的關係,只要商品列表裡面的商品數量發生變化,或減少或增多或刪除商品,總金額都應該發生變化。這裡的這個總金額使用computed屬性來進行計算是最好的選擇

與watch之間的區別:

  剛開始總是傻傻分不清到底在什麼時候使用watch,什麼時候使用computed。這裡大致說一下自己的理解:

    watch主要用於監控vue例項的變化,它監控的變數當然必須在data裡面宣告才可以,它可以監控一個變數,也可以是一個物件,但是我們不能類似這樣監控,比如:

redis,mysql 開啟事務
        # 開啟mysql事務
        with transaction.atomic():
            # 記錄事務回滾點
            save_id = transaction.savepoint()
            # 生成訂單
            order = Order.objects.create(
                order_title="路飛學城課程購買",
                total_price=150, # 未優惠的價格
                real_price=100, # 支付寶實際支付價格
                order_number=order_number, # 訂單號
                order_status=0,
                pay_type=validated_data.get("pay_type"), # 支付方式
                credit=validated_data.get("credit",0), # 使用的積分數量
                coupon=validated_data.get("coupon",0), # 使用者優惠券ID
                order_desc="", # 訂單描述
                user_id=user_id
            )

            # 然後生成訂單詳情[記錄本次下單的所有商品課程資訊]
            cart_bytes_dict = redis_conn.hgetall("cart_%s" % user_id )
            selected_bytes_list = redis_conn.smembers("select_%s" % user_id )

            # 開啟redis事務操作
            pipe = redis_conn.pipeline()
            pipe.multi()

            # 獲取勾選的商品
            for course_id_bytes,expire_id_bytes in cart_bytes_dict.items():
                course_id = int( course_id_bytes.decode() )
                expire_id = int( expire_id_bytes.decode() )
                # 判斷商品課程ID是否在勾選集合中
                if course_id_bytes in selected_bytes_list:
                    try:
                        course = Course.objects.get(is_show=True, is_deleted=False, pk=course_id)
                    except Course.DoesNotExist:
                        # 回滾事務[把save_id宣告到這裡的中間所有執行的sql語句執行產生的影響抹除]
                        transaction.savepoint_rollback(save_id)
                        raise serializers.ValidationError("對不起,購買的商品不存在或者已下架!")

                    # 校驗課程有效期價格
                    original_price = course.price
                    try:
                        if expire_id > 0:
                            coruseexpire = CourseExpire.objects.get(id=expire_id)
                            original_price = coruseexpire.price
                    except CourseExpire.DoesNotExist:
                        pass

                    real_price = course.real_price(expire_id)
                    # 生成訂單詳情
                    try:
                        OrderDetail.objects.create(
                            order=order,
                            course=course,
                            expire=expire_id,
                            price=original_price, #原價
                            real_price=real_price, # 優惠後價格
                            discount_name=course.discount_name # 優惠型別
                        )
                    except:
                        transaction.savepoint_rollback(save_id)
                        raise serializers.ValidationError("對不起,訂單生成失敗!")

                    # 計算訂單總價
                    order.total_price += float(original_price)
                    order.real_price += float(real_price)

                    # 移除掉已經加入到訂單裡面的購物車商品
                    pipe.hdel("cart_%s" % user_id, course_id)
                    pipe.srem("selected_%s" % user_id, course_id)
                    # 預設最終實付價格是訂單總價
                    real_price = order.total_price


                    # 校驗積分
                    try:
                        # 對總價格加入優惠券折扣
                        user_coupon_id = validated_data.get("coupon")
                        if user_coupon_id > 0:
                            user_coupon = UserCoupon.objects.get(pk=user_coupon_id)
                            if user_coupon.coupon.condition > order.total_price:
                                """如果訂單總金額比使用條件價格低,則報錯!"""
                                transaction.savepoint_rollback(save_id)
                                raise serializers.ValidationError("對不起,訂單生成失敗!當前購物車中購買商品總價格沒達到使用該優惠券的價格條件")

                            sale_num = float(user_coupon.coupon.sale[1:])
                            if user_coupon.coupon.sale[0] == "*":
                                """折扣優惠"""
                                real_price = order.total_price * sale_num
                            else:
                                """減免優惠"""
                                real_price = order.total_price - sale_num

                            order.coupon = user_coupon_id

                        # 對總價格加入積分抵扣
                        credit = validated_data.get("credit")
                        if credit > 0:
                            # 判斷積分是否超過訂單總價格的折扣比例
                            if credit > real_price * constants.CREDIT_MONEY:
                                transaction.savepoint_rollback(save_id)
                                raise serializers.ValidationError("對不起,訂單生成失敗!當前訂單中使用的積分超過使用上限!")

                            real_price = float("%.2f" % (real_price - credit / constants.CREDIT_MONEY))
                            order.credit = credit

                        order.real_price = real_price
                        order.save()
                        pipe.execute()
                    except:
                        transaction.savepoint_rollback(save_id)
                        raise serializers.ValidationError("對不起,訂單生成失敗!")
                # 返回生成的模型
            return order
點選新增監控地址
<details>
  <summary>點選新增監控地址:</summary>
  <ol
    v-for="domain in addr_ls"
    :key="domain.key">
    <br>
    {{ domain.href_name }}
    <br>
    <br>
    <el-input v-model="domain.href"/>
  </ol>
</details>
element 文字框回車事件
vue中, 使用element,這個時候使用按鍵修飾符需要加上.native
比如:
<el-input v-model="account" placeholder="請輸入賬號" @keyup.enter.native="search()"></el-input>
forEach終止迴圈
forEach 終止迴圈需要用try捕獲,然後丟擲異常的方式終止迴圈
for 迴圈可直接使用break
狀態碼
400 引數錯誤
401 沒有登入,沒認證過
403 沒有許可權訪問該資源
404 沒有該url

301 永久域名跳轉,例如: http://www.baidu.com 會跳轉到 htts://www.baidu.com

302 臨時跳轉,比如訪問某個地址,沒有登入過, 會先讓你登入,在跳轉到你想要的地址上

python 獲取本月第一天和最後一天
import calendar
import datetime
from datetime import timedelta
now = datetime.datetime.now()
this_month_start = datetime.datetime(now.year, now.month, 1)
this_month_end = datetime.datetime(now.year, now.month, calendar.monthrange(now.year, now.month)[1]) + timedelta(days=1) - timedelta(seconds=1)
修改requests請求
user_obj = request.user
params = request.GET
follow_up_search = ''
if 'as' in params:
    request.GET._mutable = True
    as_params_js_dic = request.GET.pop('as')[0]
    as_params_dic = json.loads(as_params_js_dic)
    if 'follow_up_search' in as_params_dic:
        follow_up_search = as_params_dic.pop('follow_up_search')
        if as_params_dic:
            request.GET['as'] = json.dumps(as_params_dic)
    else:
        request.GET['as'] = json.dumps(as_params_dic)
    request.GET._mutable = False
django mysql事務回滾

把try放外面, 事務放裡面, 不妨礙異常捕獲

    def list(self, request, *args, **kwargs):
        try:
            with transaction.atomic():
                FollowUp.objects.create(warning_identity_id='ASR20204161624', username_id="T30672")
                FollowUp.objects.create(warning_identity_id='ASR2020416161231224', username="3123123")
        except Exception:  # 自動回滾,不需要任何操作
            return Response(apiResult('fail', 2001, data='', msg=''))
斷言
示例:
	assert ('linux' in sys.platform), "該程式碼只能在 Linux 下執行" # 條件為 false 觸發異常
使用場景:
    使用斷言對引數進行確認.
    我打算做哪些假定, 一旦確定後,就要使用斷言對假定進行檢查
ASSERT(斷言) 只有在 Debug 版本中才有效,如果編譯為 Release 版本則被忽略
python datetime型別格式化
datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 將datetime型別, 轉換成指定的字串格式
datetime.datetime.strptime(time,'%Y-%m-%d') # 字串時間,轉換成datetime型別
or and not 的優先順序
如果 or 的兩邊結果一樣,那麼它會選擇左邊的
print(6 or 2 > 1) # 6
如果 and 兩邊左右結果一樣,則會取右邊的
print(2 > 1 and 3)

js 字典合併
方法1:
Object.assign(目標字典,被合併字典,被合併字典)
方法2:
var dic = {"a":123}
var dic2 = {"b":123}
var c = {...dic,...dic2}