【问题标题】:how to return a django view from within a celery task?如何从 celery 任务中返回 django 视图?
【发布时间】:2020-01-08 13:32:54
【问题描述】:

我需要从 django celery 任务中返回一个表单。我的任务是从以下 django 视图调用的:

class MyView(CreateView):
    model = MyModel
    form_class = MyForm
    success_url = '/create/form'

    def form_valid(self, form):
        form.save()
        # I call my task in here
        period.delay()
        print("Loading task...")

        return super(MyView, self).form_valid(form)

我的任务名称是 "period",当我的 IF 中的条件为真时,它将日期与打开事件的目标进行比较。我的“事件”是一个用户必须确认存在的公式。

我的任务:

from .views import MyAnotherView 
# others imports...

"""
    in my settings.py, I had to call tha task every minute:
    CELERYBEAT_SCHEDULE = {
    'add-periodic-events': {
        'task': 'myapp.tasks.period',
        'schedule': crontab(minute='*'),
        }
    }
"""

@shared_task(serializer='json')
def period():
    event = MyModel.objects.get(id=1) # I limited my model to receive only one object

    request = RequestFactory.get('/another/form') 
    view = MyAnotherView() 

    week_d = week_day(event.day) # day is a field of my model
    event_d = event_day(week_d, event.hour) # hour is a field of my model
    conf_d = presence_confirm(event.before_days, event.begin_hour, event_d) # before_days and begin_hour are fields of my model

    utc_now = pytz.utc.localize(datetime.utcnow())
    n = utc_now.astimezone(pytz.timezone('America/Recife'))
    t_str = '{}-{}-{}'.format(n.year, n.month, n.day)
    t_hour = ' {}:{}'.format(n.hour, n.minute)

    today = t_str + t_hour
    today = datetime.strptime(today, '%Y-%m-%d %H:%M')

    if (today >= conf_d) and (today < event_d):
        # HOW TO CALL MY FORMULARY???
        print("Call my formulary")
        view.setup(request)

    else:
        # another thing

在调用我的任务并且条件为真时我想显示的公式它将来自以下 django 模型:

class MyAnotherModel(models.Model):
    OPTIONS = (
        (True, 'Sim'),
        (False, 'Não'),
    )

    player = models.OneToOneField(MyUserModel, primary_key=True, on_delete=models.CASCADE)
    confirm = models.BooleanField(choices=OPTIONS, default=False)
    modified = models.DateTimeField(auto_now_add=True)

简而言之,我希望在我的条件成立时出现我的处方集。因此,我尝试在我的任务中使用 RequestFactory.get 来捕获 URL 并调用视图 (MyAnotherView)。

     # ...
     request = RequestFactory.get('/another/form') 
     view = MyAnotherView() # View responsável em instanciar MyAnotherModel 
     # ...
     if (today >= conf_d) and (today < event_d):
        view.setup(request)

但是,我收到了 ImportError: cannot import name 'MyAnotherView'。如果有人可以帮助我,我很感激!

【问题讨论】:

  • 嗯,你的错误很清楚,它只是说你没有在.views 中定义MyAnotherView。您必须向我们展示文件夹结构才能了解它为什么无法导入。但我的主要问题是关于你在这里想要做什么。您的 celery 任务未在请求周期内运行,因为它是异步的。所以“显示视图”是不可能的。向谁展示?用户的原始请求已经收到来自MyView 的响应,因此浏览器没有等待任何内容。
  • @dirkgroten,相信我,我的结构是正确的。确实有点混乱。为此表示歉意!我想要的是在一段时间内启用表单,以便我的用户可以填写它。我有一个活动的时间以及用户可以确认出席的时间。正是在这个时间间隔(确认出席和活动当天之间),我想启用我的表格。如果有其他方法可以告诉我,我很感激。
  • “我的处方集出现”是什么意思(无论如何,处方集是什么)?出现在哪里?如果你想检查一个表单是否应该显示,为什么你需要一个异步任务呢?你的问题和解释毫无意义。
  • 我想要一个能够填写我提到的时间范围的表格。为了检查今天是否与用户提供的时间范围相匹配,我使用了 celery,如上所示。从现在开始,我想在用户点击链接时向他们启用/显示/,类似的。我不知道这是否是最好的方法。抱歉不清楚。我对芹菜一无所知,无法提出“理想”的问题,对此感到抱歉,但我正在努力做到尽可能清楚。

标签: django django-celery celery-task


【解决方案1】:

我的问题是检查今天的日期是否在两个日期之间。如果是这样,我必须“显示”一个表格。我用芹菜做的这个检查。我的问题是,只要今天的日期在启用表格的日期之间,我该怎么做。 我解决了如下问题:

  • 我的 celery 任务没有在请求周期内运行,因为它是异步的 - @dirkgroten - 我很快想到在我的 django 模型 (MyModel) 中创建一个新字段:
enable = models.BooleanField(default=False)
  • 在我的任务中更新此字段:
    # ...
    if (today >= conf_d) and (today < event_d):
        event.enable = True
        event.save()

    else:
        event.enable = False
        event.save()
  • 在我的表单视图中将此信息作为我的模板中的上下文返回
    # In MyAnotherView
    model = MyAnotherModel
    fields = ['player', 'confirm']
    success_url = '/list/users'
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        obj = MyModel.objects.get(id=1)
        context['enable'] = obj.enable
        return context
<!--This is the template that shows form-->
{% if enable %}
    {{ form }}
{% else %}
    <h2> Don't show <h2>
{% endif %}

如果有人认为有更好的方法,他们可以建议我,但我现在会给出答案。

【讨论】:

    猜你喜欢
    • 2019-07-02
    • 2020-12-18
    • 2020-12-27
    • 2013-08-30
    • 2015-11-19
    • 2016-11-11
    • 2018-11-13
    • 2018-12-20
    • 2021-01-24
    相关资源
    最近更新 更多