首页 > 解决方案 > Django 管理员自定义操作请求

问题描述

我编写了一个自定义操作,并通过模型权限将这些权限授予了 2 个用户。

但现在我只希望其中一个在任何时候运行它。因此,每当他们选择actionbox并按下操作按钮时,它都会考虑request.POST是否已经制作了 a。

所以我的问题是HTTP,在将用户带到中间页面并显示消息之前,我是否可以询问是否有任何其他请求?但无需挖掘服务器日志。

标签: djangohttp

解决方案


退一步说,我认为您真正要问的是如何在应用程序的入口点之间共享数据。例如,如果您只希望 1 人能够一次触发按钮上的操作。

执行此操作的一种策略是获取一些部署范围内可访问的数据存储(例如,部署的所有实例都可以访问的缓存或消息队列)并在其中放入一条消息,就像锁一样。这将依赖该数据存储来支持原子读写。在 Django 中,redis 或 memcached 之类的东西可以很好地用于此目的(尤其是如果您将其用作缓存后端。)

你可能有这样的东西(示例取自 celery 文档):

from datetime import datetime, timedelta
from django.core.cache import cache
from contextlib import contextmanager

LOCK_EXPIRE = 600 # Let the lock timeout in case your code crashes.

@contextmanager
def memcache_lock(lock_id):
    timeout_at = datetime.now() + timedelta(seconds=LOCK_EXPIRE)
    # cache.add fails if the key already exists
    status = cache.add(lock_id, 'locked', LOCK_EXPIRE)
    try:
        yield status
    finally:
        if datetime.now() < timeout_at and status:
            # don't release the lock if we exceeded the timeout
            # to lessen the chance of releasing an expired lock
            # owned by someone else
            # also don't release the lock if we didn't acquire it
            cache.delete(lock_id)


def my_custom_action(self, *args, **kwargs):
    lock_id = "my-custom-action-lock"
    with memcache_lock(lock_id) as acquired:
        if acquired:
            return do_stuff()
        else:  
            do_something_else_if_someone_is_already_doing_stuff()
            return

推荐阅读