环境
UI : element ui
Vue: 2.6
Django:3.1.4
Demo
背景
当前时间选择器主要有两种状态
-
用户选择时间,有值;
-
用户清除时间,值为null。
有值啥都好说,没值的话,前端不做空值处理,会报错,后端Django orm 查询时间区间也会报错,我们要充分考虑可能发生的异常。
意味着要做两次异常处理,一次是前端清除选择,一次是后端判断前端URL传空值的校验
时间选择器每次产生值,都要从第一页开始,重置当前页面为1,保证分页查询不超出后端分页范围
原理图
前端代码
template
<el-col :span="5">
<div class="block">
<el-date-picker @change="selectTime" v-model="TimeSelect.SelectTimeValue" type="daterange" align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" unlink-panels range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions">
</el-date-picker>
</div>
</el-col>
scripts - data
data() {
return {
TimeSelect: {
SelectTimeValue: ''
},
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
receiverInfos: [],
SelectDataListTpl:{project_name:''},
currentPage: 1, //默认显示页面为1
pagesize: 10, // 每页的数据条数
total:0
};
},
scripts - methods
methods: {
// 时间选择器
selectTime(val){
if (this.TimeSelect.SelectTimeValue === null) {
this.getReceiverInfos()
}else {
this.TimeSelect.SelectTimeValue = val;
console.log(val);
this.loading=true
this.$http({
method: "get",
url: "/api/AllSelectAllPublicPageProjectDateSelect",
params: {
currentpage: this.currentPage,
pagesize:this.pagesize,
startDate:val[0],
endDate:val[1]
},
})
.then(result => {
this.loading=false
this.total = result.data.total;
this.receiverInfos = result.data.data;
})
.catch(err => {
console.dir(err);
});
}
},
// table 数据
getReceiverInfos() {
if (this.TimeSelect.SelectTimeValue === null){
this.TimeSelect.SelectTimeValue = []
}
this.currentPage = 1
this.loading=true
this.$http({
method: "get",
url: "/api/url",
params: {
currentpage: 1,
pagesize:this.pagesize,
startDate: this.TimeSelect.SelectTimeValue[0],
endDate: this.TimeSelect.SelectTimeValue[1]
},
})
.then(result => {
this.loading=false
this.total = result.data.total;
this.receiverInfos = result.data.data;
})
.catch(err => {
console.dir(err);
});
},
}
};
后端代码
class AllSelectAllPublicPageProjectDateSelect(APIView):
def get(self, request, format=None):
response = {
'code': HTTP_200_OK,
'msg': '查询成功',
'data': [],
'total': int
}
start_date = request.GET.get('startDate')
end_date = request.GET.get('endDate')
if start_date is None:
queryset = PublicPage.objects.filter(project_delete=0).order_by(
"-update_time")
else:
queryset = PublicPage.objects.filter(project_delete=0, create_time__range=(start_date, end_date)).order_by(
"-update_time")
SelectPublicPageDataTotal = queryset.count()
page_obj = MyPageNumber()
page_PublicPageData = page_obj.paginate_queryset(queryset=queryset, request=request, view=self)
ser_obj = publicPageSerializer(page_PublicPageData, many=True)
response['data'] = ser_obj.data
response['total'] = SelectPublicPageDataTotal
return Response(response, status=200)