Django 怎么做同一个 url,对应不同的 view 函数? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
elboble
V2EX    Django

Django 怎么做同一个 url,对应不同的 view 函数?

  •  
  •   elboble 2022-08-29 16:16:31 +0800 3234 次点击
    这是一个创建于 1144 天前的主题,其中的信息可能已经有所发展或是发生改变。

    类似于那种定时抢购的逻辑。

    时间没到之前是个介绍页面,时间到了之后进入真正的 view 处理函数。

    触发条件不一定是时间,也可能是后台控制的。就是要做到程序不重启,同一 url 对应的 view 变了。

    我是这样做的,加了个全局变量,然后在 url 对应个 view 函数里做判断,后台改变这个全局变量,执行不同的 view 函数。

    IS_RELEASE 是全局变量,entrance 函数是入口函数,release 函数是改变入口的视图函数。

    IS_RELEASE = False

    def entrance(request):
    global IS_RELEASE
    if IS_RELEASE:
    return index2022(request)
    else:
    return index2(request)

    @login_required
    def release(request):
    global IS_RELEASE
    if IS_RELEASE:
    IS_RELEASE = False
    else:
    IS_RELEASE = True
    return redirect("/conf/")

    这个方法在本地调试没问题,但是上到服务器后,出现执行 release 函数后 IS_RELEASE 没按预期改变,或者有秒级的延迟,我猜是不是有 cdn 的影响,但是这个都应该是动态页面,每个请求都要回服务器处理的。

    14 条回复    2023-11-02 11:25:06 +08:00
    676529483
        1
    676529483  
       2022-08-29 16:22:18 +08:00
    你服务器肯定不是 runserver 启动的吧?走 gunicorn 、uwsgi 等等,都是多进程的,全局变量只是进程唯一的,可以改成从一个地方去拿,比如 redis 、mysql
    elboble
        2
    elboble  
    OP
       2022-08-29 16:24:20 +08:00
    @676529483 是的 supervisor 启动的
    676529483
        3
    676529483  
       2022-08-29 16:25:32 +08:00
    @elboble supervisor 只是进程管理,启动命令可以贴下
    elboble
        4
    elboble  
    OP
       2022-08-29 16:40:35 +08:00
    [uwsgi]
    chdir = /home/xxxx/project/xxxx
    module = xxxx.wsgi
    home = /home/xxxx/venv/venv3.9
    master = true
    processes = 2
    socket = 0.0.0.0:8909
    vacuum = true
    zxzflower
        5
    zxzflower  
       2022-08-29 16:53:46 +08:00
    用 redis 或者数据库 做个访问开关,你只要有多个 worker ,你的方法就会混乱的,甚至 worker 还会 restart
    bulay
        6
    bulay  
       2022-08-29 16:57:37 +08:00
    如果是单台服务器直接用 django.core.cache,本地缓存.
    AndyVTEX
        7
    AndyVTEX  
       2022-08-29 17:45:35 +08:00
    是啊,肯定是 redis 或者数据库开关呀,环境变量是什么骚操作
    lanlanye
        8
    lanlanye  
       2022-08-29 20:04:43 +08:00 via iPhone
    建议你把要渲染的模板做成 Model ,需要时直接去 DjangoAdmin 里改……
    elboble
        9
    elboble  
    OP
       2022-08-29 23:42:09 +08:00
    感谢各位大佬,用 redis 存了状态,基本实现了功能,上服务器也没问题了。

    还有几点请教:
    1 ,用 uwsgi 起多个 worker ,实际上是多个 django 的实例在跑,这样如果用 uwsgi 来启动 django ,djaongo 中是不存在只运行一次的代码。
    我这个问题中,即使用 redis 也有个初始值的坑。最简单的是在程序之外,程序启动之前,用 redis-cli 手动设定初始值。如果不用这个方法,就想是不是能在 django 初始化的地方,运行一次 redis set 初始值。通过上面的分析,django 用 uwsgi 启动是不存在这样只执行一次的代码,至少每个 worker 启动 django 所有的代码都要跑一遍,有几个 worker 就要跑几遍。
    后来我想通过 redis 直接 get 键取值,但是 redis 的 get 不像 json 的 get 读取空时能返回一个默认值,这个真没想到,自己简单包装了一个能返回默认值的,来代替原始的 conn.get()。这样就不需要预先设置 redis 了。
    cOnn= redis.Redis(connection_pool=POOL)
    IS_RELEASED_KEY = 'xxxx_is_released'
    def rget(key):
    ret = conn.get(key)
    if ret == None:
    return '0'
    else:
    return ret

    2 ,取得 redis 的 conn 是在 view.py 中,但是不在任何一个 view 函数中,这个代码是不是每个 worker 只执行一次,有几个 woker 就有几个不同的 conn ,还是每次请求都会建新的 conn ?
    huangzhiyia
        10
    huangzhiyia  
       2022-08-31 16:45:15 +08:00 via Android
    一个小功能还是不要上 redis 了吧,在 django 中类似全局变量效果,请直接用 django 内置的
    cache 。
    elboble
        11
    elboble  
    OP
       2022-08-31 23:36:14 +08:00
    @zmaplex redis 本来就开了,给 celery 用的,这个比建个表 migrate 方便点。
    gaogang
        12
    gaogang  
       2022-09-05 18:01:59 +08:00
    @elboble uwsgi 启多个 worker 不是 preload 的方式,所以这种写法的话,每个 worker 中在使用到 view.py 时会创建一个 conn
    programMrxu
        13
    programMrxu  
       2023-11-01 17:20:21 +08:00
    为什么这里的值不会改变呢?我在本地跑了两个线程,去修改一个全局变量,他的值是会发生变化的。
    elboble
        14
    elboble  
    OP
       2023-11-02 11:25:06 +08:00
    @programMrxu 我理解是 uwsgi 接受每个请求,是单独开个 django 进程,所以即使全局变量也不能共享,“全局”仅在 django 进程内。所以用系统级的 redis ,杀鸡用牛刀了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5537 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 07:32 PVG 15:32 LAX 00:32 JFK 03:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86