ModelViewSet额外路由参数 与 ADMIN事件触发

ModelViewSet额外路由参数

用了DefaultRouter,那么在URL匹配时带路径参数,只有update、delete、retrieve能带,关键是匹配pk还是写死的,我们需要对任意参数,同时还能修改方法命名。

咋搞?很简单。比如我们要在HahaViewSet里写一个xixi的GET haha/{name}/xixi/的接口。

第一步路由:

router = routers.DefaultRouter()
router.register(r'haha', haha.HahaViewSet, basename="haha")

urlpatterns = [
    path('', include(router.urls)),
    url(r'haha/(?P<name>\w+)/xixi/$', haha.HahaViewSet.as_view({'get': 'xixi'})),
    ...
]

第二步方法:

@swagger_auto_schema(...)
@action(detail=False, methods=["GET"], url_path="")
def xixi(self, request, *args, **kwargs):  # 方法名字要与路由匹配的action字典匹配上
    name = kwargs.get("name")  # 没有带name,url的w+就不会匹配到,直接404
    ...

ADMIN事件触发

通常在使用Django框架后,定义models时,我们往往会把使用字段放在/admin可访问里,这样比直接去操作DB客户端简单些,而且在实际开发中并不是人人都有去权限去修改DB,就算有修改起来也比较麻烦。

举个使用例子吧,先定义一个model在models.py

class Haha(models.Model):
    name = models.CharField(verbose_name="姓名", max_length=50, db_index=True)

    class Meta:
        verbose_name = "哈哈表"
        verbose_name_plural = "哈哈表"

那么在admin.py文件就可以加上admin定义:

@admin.register(models.Haha)
class HahaAdmin(admin.ModelAdmin):
    list_display = ["name"]
    search_fields = ["name"]

这是个很基本的例子,但如果现在我们的项目用上了缓存呢。

那么在 /admin 增删改根本就不会影响到缓存,而往往我们逻辑上的诉求是在 /admin后台增删改时可以把对应的缓存删掉,待接口调数据调不到时去DB拿,再更新到缓存,admin删除缓存怎么办呢?

这就需要两个东西admin触发事件与model信号,解决admin增删改缓存不一致的问题。

需要重新两个方法(

        save_model, delete_model

)和利用信号机制编写一个信号接收函数(自定义命名)。

from django.contrib import admin
from django_redis import get_redis_connection
from . import models


@admin.register(models.Haha)
class HahaAdmin(admin.ModelAdmin):
    list_display = ["name"]
    search_fields = ["name"]

    def save_model(self, request, obj, form, change):
        # 删除缓存
        get_redis_connection().delete("%s_key" % obj.name)  
        # super().save_model(request, obj, form, change)源码也是这个
        obj.save()  
    
    def delete_model(self, request, obj):
        # 删除缓存
        get_redis_connection().delete("%s_key" % obj.name)  
        # super().delete_model(request, obj)源码也是这个
        obj.delete()

上面是完整的代码,写到这里有小伙伴就拿去测试了,发现为啥删除的时候,缓存去不掉。

这里就有一个特别大的操作误区了。如何才会触发这两个函数。

自行去测试会发现,只对这里的删除和保存才会触发save_model, delete_model。

保存还好,只有这一种保存方式,那么删除呢?

删除还有直接在页面选中删除的方式,这就触发不到delete_model。

这时候就需要信号接受函数,sender就为对应的model

from django.db.models.signals import post_delete
from django_redis import get_redis_connection
from django.dispatch import receiver

@receiver(post_delete, sender=Haha)
def delete_cache(sender, instance, **kwargs):
    # 删除缓存
    get_redis_connection().delete("%s_key" % name)  

OK,到这里大功告成。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值