1. 前端
1.1 app.json配置(默认不支持下拉)
局部配置,如果想全局都可以下拉,那配置在全局的app.json即可
{
"enablePullDownRefresh": true
}
1.1 html
<!-- 表面信息 -->
<view class="index_item" wx:for="{{ index_data_list }}" wx:key="index">
<navigator url="/pages/inside/inside?id={{ item.id }}"> <text>用户:{{ item.nickName }}</text> </navigator>
<text>内容:{{ item.content }}</text>
<text>话题:{{ item.topic }} </text>
<text>发布时间:{{ item.update_time }}</text>
</view>
1.2 js
// pages/index/index.js
var api = require('../../config/app')
Page({
/**
* 页面的初始数据
*/
data: {
index_data_list: [],
MinId: 0,
MaxId: 0
},
/**
* 生命周期函数--监听页面加载
*/
initMessage: function () {
wx.request({
url: api.IndexAPI,
dataType: "json",
method: "GET",
success: (res) => {
this.setData({
index_data_list: res.data,
MinId: res.data[res.data.length - 1].id,
MaxId: res.data[0].id
})
},
})
},
onLoad: function (options) {
this.initMessage();
},
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
this.pullData(true);
},
pullData: function (status) {
if (!status) {
wx.request({
url: api.IndexAPI,
data: {
min_id: this.data.MinId
},
dataType: "json",
method: "GET",
success: (result) => {
// console.log(result.data)
if (result.data.length > 0) {
this.setData({
index_data_list: this.data.index_data_list.concat(result.data),
MinId: result.data[result.data.length - 1].id,
//MaxId: result.data[0].id
})
} else {
wx.showToast({
title: '到底部啦',
icon: "none"
})
return
}
},
})
} else {
wx.request({
url: api.IndexAPI,
data: {
max_id: this.data.MaxId
},
dataType: "json",
method: "GET",
success: (result) => {
// console.log(result.data)
var new_list = result.data.reverse() // 数据是正向的
if (new_list.length > 0) {
this.setData({
index_data_list: new_list.concat(this.data.index_data_list),
MinId: new_list[new_list.length - 1].id,
MaxId: new_list[0].id
})
} else {
wx.showToast({
title: '无最新动态',
icon: "none"
})
return
}
},
})
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
//
this.pullData(false);
},
})
2. 后端
2.1 url
# 首页内容
path('index/data/', views.IndexDataListAPIView.as_view()),
2.2 view
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView
from utils.private import filters, pagination
from .serislizer import IndexDataModelSerializer
class IndexDataListAPIView(ListAPIView):
"""首页展示信息"""
queryset = models.Release.objects.filter(is_show=True, is_delete=False).order_by('-id')
serializer_class = IndexDataModelSerializer
filter_backends = [filters.MaxFilterBackend, filters.MinFilterBackend]
pagination_class = pagination.DataLimitPagination
2.3 filter
from rest_framework.filters import BaseFilterBackend
class MinFilterBackend(BaseFilterBackend):
"""
前端传:min_id/max_id
"""
def filter_queryset(self, request, queryset, view):
# 给视图类的queryset,添加新的条件
# 就是我们在类里面配置的
# queryset=models.Release.objects.filter(is_show=True, is_delete=False).order_by('-id')
min_id = request.query_params.get('min_id')
print(min_id)
if min_id:
return queryset.filter(id__lt=min_id).order_by('-id')
return queryset
class MaxFilterBackend(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
max_id = request.query_params.get('max_id')
if max_id:
return queryset.filter(id__gt=max_id).order_by('id')
return queryset
2.4 page
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response
class DataLimitPagination(LimitOffsetPagination):
"""
本质上帮助我们进行切片的处理:[0:N]
"""
default_limit = 10 # 默认返回数据
max_limit = 50 # 最大返回数据
limit_query_param = 'limit' # 前端查询的参数
offset_query_param = 'offset'
# offset 偏移数 GET http://127.0.0.1/four/students/?limit=100&offset=400 从下标为400的记录开始,取100条记录
def get_offset(self, request):
# 重写偏移数,修改成0
return 0
def get_paginated_response(self, data):
# 修改返回的界面,把多余的去掉,比如总数据,上一页/下一页
return Response(data)
2.5 serializer
class IndexDetailDataModelSerializer(serializers.ModelSerializer):
"""首页的详情页返回的数据"""
topic = serializers.CharField(source='topic.name')
nickName = serializers.CharField(source='userinfo.nickName')
class Meta:
model = models.Release
fields = [
'id', 'position', 'content', 'topic', 'nickName', 'update_time', 'msg_url'
]
2.6 models
class Release(BaseModel):
"""发布"""
position = models.CharField(verbose_name='位置', max_length=225, blank=True, null=True)
content = models.CharField(verbose_name='内容', max_length=225)
fucking_great = models.CharField(verbose_name='点赞', default=0, max_length=666)
watch_num = models.CharField(verbose_name='观看人数', default=0, max_length=666)
comment = models.ForeignKey(verbose_name='评论', to='self', on_delete=models.DO_NOTHING, db_constraint=False,
null=True, blank=True, related_name='release')
# db_constraint=False db_constraint=False 逻辑上的关联,实质上没有外键联系,增删不会受外键影响,orm查询不影响
userinfo = models.ForeignKey(verbose_name='用户', to='UserInfo', on_delete=models.DO_NOTHING, db_constraint=False)
topic = models.ForeignKey(verbose_name='话题', to='Topic', on_delete=models.DO_NOTHING, db_constraint=False)
# 图片链接拼接
@property
def cover_msg_url(self):
# 每一个对象走一遍
msg_url = self.media.all().filter(is_show=True, is_delete=False).first().cosUrl
# print(msg_url)
return msg_url
# 图片链接拼接
@property
def msg_url(self):
msg_url = self.media.all().filter(is_show=True, is_delete=False).values('cosUrl')
return msg_url
class Media(BaseModel):
name = models.CharField(verbose_name='名称', max_length=225, blank=True, null=True)
choice_type = (
(1, "无"),
(2, "图片"),
(3, "视频"),
)
type = models.SmallIntegerField(verbose_name='类型', default=1)
cosUrl = models.CharField(verbose_name='路径', max_length=225, blank=True, null=True)
release = models.ForeignKey(verbose_name='发布', to='Release', related_name='media', on_delete=models.DO_NOTHING,
db_constraint=False,
null=True, blank=True)
cosETag = models.CharField(verbose_name='校验信息', max_length=225, blank=True, null=True)
cos_media_name = models.CharField(verbose_name='cos图片名称,删除使用', max_length=225, default='1.png')
class Topic(BaseModel):
"""话题"""
name = models.CharField(verbose_name='话题名称', max_length=225)
people_num = models.BigIntegerField(verbose_name='关注人数')
class Meta:
verbose_name = "话题"
verbose_name_plural = "话题"