路飞-轮播图功能-缓存定时任务
路飞-后端首页轮播图接口
轮播图属于首页功能,后端在apps内创建home 在homeapp中创建banner表
由于很多表有公共的字段,那我们就可以把公共的字段创建一个类 然后用表继承
这样所有的表都有公共字段了
1.在utils下新建 common_model.py 文件中编写公共字段类
from django.db import models
# Create your models here.
class BaseClass(models.Model):
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
is_delete = models.BooleanField(default=False, verbose_name='是否删除')
is_show = models.BooleanField(default=True, verbose_name='是否展示')
orders = models.IntegerField(verbose_name='优先级')
class Meta:
abstract = True
# 该字段意思 虚拟表,不需要在数据库创建 只用来继承
2.在models中编写banner表
from LufeiApi.utils.common_models import BaseClass
from django.db import models
class Banner(BaseClass):
title = models.CharField(max_length=32, verbose_name='广告名称')
image = models.ImageField(upload_to='banner', verbose_name='图片地址')
ilnk = models.CharField(max_length=64, verbose_name='跳转链接')
info = models.TextField(verbose_name='详情')
class Meta:
db_table = 'luffy_banner'
verbose_name_plural = '轮播图表'
def __str__(self):
return self.title
3.编写视图函数
3.1控制返回格式 编写MyListModel继承yListModelMixins
from rest_framework.mixins import ListModelMixin
from LufeiApi.utils.common_response import MyResponse
class MyListModel(ListModelMixin):
def list(self, request, *args, **kwargs):
res = super().list(request, *args, **kwargs)
return MyResponse(data=res.data)
# 这样返回的格式就会安装我们封装的MyResponse返回
3.2 编写是函数
from rest_framework.viewsets import GenericViewSet
from .models import Banner
from .serializer import BannerSerializer
from LufeiApi.utils.common_mixins import MyListModel
class BannerView(GenericViewSet, MyListModel):
queryset = Banner.objects.filter(is_show=True, is_delete=False).order_by('orders')
serializer_class = BannerSerializer
4.编写序列化类(控制前后端传输的字段)
from rest_framework import serializers
from .models import Banner
class BannerSerializer(serializers.ModelSerializer):
class Meta:
model = Banner
fields = ['id','image','ilnk','orders','title']
# 控制给前端的数据
总路由分发
每个app都是各自的urls.py文件
我们需要在总路由中 设置路由分发
from django.contrib import admin
from django.urls import path, include
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/home/', include('LufeiApi.apps.home.urls')),
# 每一个app都需要在这里注册一下
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT}),
]
app内子路由
from rest_framework.routers import SimpleRouter
from LufeiApi.apps.home import views
router = SimpleRouter()
router.register('banner',views.BannerView,'banner')
urlpatterns = [ ]
urlpatterns += router.urls
# 地址:ip+端口+总路由'api/v1/home/'+子路由'banner' 就可以出发对应的功能
通过simpleui录入数据
# 主站前后端分离
# 后台管理使用django 的admin做的---》simpleui
# 使用步骤:
第一步:安装simpleui
pip install django-simpleui
第二步:注册app
'simpleui',
第三步:在对应app的admin.py中注册表
from .models import Banner
admin.site.register(Banner)
轮播图前端代码
组件化 首页插入轮播图组件即可
<template>
<el-carousel height="400px" :interval="5000" arrow="always">
# 控制轮播图控件大小 轮播切换秒数
<el-carousel-item v-for="item in img_list" :key="item.id">
<div v-if="item.link.indexOf('http')>-1">
# 判断轮播图地址是否是外链,外链就用a标签 不是就router-link
<a :href="item.link">
<img :src="item.image" :alt="item.title">
</a>
</div>
<div v-else>
<router-link :to="item.link">
<img :src="item.image" :alt="item.title">
</router-link>
</div>
</el-carousel-item>
</el-carousel>
</template>
<script>
created() {
this.$axios.get(this.$settings.BASE_URL + '/home/banner/').then(res => {
# 发送请求到后端拿取轮播图数据
if (res.data.code == 100) {
this.img_list = res.data.data
} else {
this.$message(res.data.msg)
}
}).catch(res => {
this.$message('轮播图服务器异常,请稍后再试')
})
}
</script>
/
接口添加缓存功能
有一些访问数据的接口,我们可以添加缓存,这样大大减少mysql的访问次数增加应用健壮性
eg:给banner接口加缓存
逻辑:
当用户第一次访问该接口,查看redis缓存中是否有数据 有就用缓存的没有再访问数据库
然后把数据库里面的数据 存到缓存中,用户再次访问就是直接用缓存中的数据了
from django.core.cache import cache
# cache模块可以更改配置文件 让 cache连接redis
class BannerView(GenericViewSet, ListModelMixin):
queryset=Banner.objects.filter(is_show=True,is_delete=False).
order_by('orders')
serializer_class = BannerSerializer
def list(self, request, *args, **kwargs):
banner_list = cache.get('banner_list')
# 通过django的缓存功能模块 去查是否有banner_list的缓存数据 如果有则用这个
if banner_list:
return MyResponse(result=banner_list)
else:
res = super().list(request, *args, **kwargs)
# 没有则去mysql里查数据 然后更新存到缓存中
banner_list = res.data
cache.set('banner_list',banner_list)
return MyResponse(result=banner_list)
数据一致性问题
如果缓存中有了数据,那就会一直使用缓存中的数据,这样就有一个问题
如果 我们更改了mysql数据,但是用户访问的还是缓存数据
由于banner接口时效性没有那么强,所以我们可以使用定时任务,每1小时清除一下redis的缓存
这样来保证 每一个小时redis数据更新一次,redis数据和mysql数据相对一致性
这里的定时任务 用的是celery模块
# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False
# 任务的定时配置
from celery.schedules import crontab
app.conf.beat_schedule = {
'home_banner': {
'task': 'celery_pack.task.home_banner_task',
'schedule': timedelta(minutes=30),
# 时间对象 每30分钟更新一次
# 'schedule': crontab(hour=23,minute=58), # 每天晚上23点58分执行
# 'args': (300, 150),
},
}
@app.task
def home_banner_task():
cache.delete('banner_list')
celery -A celery_pack worker -l info
开启执行任务
celery -A celery_pack beat -l info
开启定时器
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了