...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() 方法用于把数组中的所有元素放入一个字符串。作用是将数组转换为字符串,其作用和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);
},
import os
import time
# 格式化成2016-03-20 11:45:39形式
monthTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
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)
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);
}
var startTime = Date.parse(new Date()) / 1000; // 获取秒级时间戳
var endTime = Date.parse(new Date()) / 1000;
JSON.stringify(this.file_ls); // 序列化
JSON.parse(this.file_path) // 反序列化
<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); // 再把集合转换成数组
var assignObj = Object.assign(params, this.params);
属性 | 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) # 排除在某个范围的内容
# 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
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;
}
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_conn.delete(‘identity_%s‘ % yesterday_identity)
序列化最后走的是序列化器中定义的方法
反序列化时, 它会先走数据库, 根据数据库字段名和它的类型, 对照着反序列化, 所以你提交的字段名字需要跟数据库中的名字相对应, 这样才能在校验后的数据中获取到, 否则只能在元数据(self.initial_data) 获取
# 序列化器
def create(self,validated_data):
name = validated_data.get(‘name‘) # 这里获取的都是反序列化后的内容, 也就是跟数据库字段想对应的内容,并且也已经将类型反序列化好了
name = self.initial_data.get(‘name‘) # 这里获取的都是没有经过反序列化校验的内容,一般都是字符串
[^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 # 存储器
传递到组件中的内容需要进行json反序列化
JSON.parse(xxx)
str(hou_title).zfill(3)
js 判断数组中是否有某个值
Arry.includes(‘Admin‘);
模型中的ForeignKey字段,添加数据,要给个实例对象
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
转自: https://www.cnblogs.com/gunelark/p/8492468.html
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择
与watch之间的区别:
刚开始总是傻傻分不清到底在什么时候使用watch,什么时候使用computed。这里大致说一下自己的理解:
watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象,但是我们不能类似这样监控,比如:
# 开启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>
vue中, 使用element,这个时候使用按键修饰符需要加上.native
比如:
<el-input v-model="account" placeholder="请输入账号" @keyup.enter.native="search()"></el-input>
forEach 终止循环需要用try捕获,然后抛出异常的方式终止循环
for 循环可直接使用break
400 参数错误
401 没有登录,没认证过
403 没有权限访问该资源
404 没有该url
301 永久域名跳转,例如: http://www.baidu.com
会跳转到 htts://www.baidu.com
302 临时跳转,比如访问某个地址,没有登录过, 会先让你登录,在跳转到你想要的地址上
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)
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
把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 版本则被忽略
datetime.datetime.now().strftime(‘%Y-%m-%d %H:%M:%S‘) # 将datetime类型, 转换成指定的字符串格式
datetime.datetime.strptime(time,‘%Y-%m-%d‘) # 字符串时间,转换成datetime类型
如果 or 的两边结果一样,那么它会选择左边的
print(6 or 2 > 1) # 6
如果 and 两边左右结果一样,则会取右边的
print(2 > 1 and 3)
方法1:
Object.assign(目标字典,被合并字典,被合并字典)
方法2:
var dic = {"a":123}
var dic2 = {"b":123}
var c = {...dic,...dic2}
原文:https://www.cnblogs.com/lgw1171435560/p/13332294.html