как вернуть django представление из задачи сельдерея? - PullRequest
0 голосов
/ 08 января 2020

Мне нужно вернуть форму из задачи django из сельдерея. Моя задача вызывается из следующего представления 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" . Оно сравнивает даты с целью открыть событие, пока выполняется условие по моему ЕСЛИ верно. Мой «событие» - это формула, которую пользователь должен подтвердить присутствие.

Моя задача:

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: невозможно импортировать имя 'MyAnotherView' . Если кто-нибудь может мне помочь, я приветствую!

1 Ответ

0 голосов
/ 08 января 2020

Моя проблема заключалась в проверке, находится ли сегодняшняя дата между двумя датами. Если это так, я должен «показать» форму. Эту проверку я сделал с сельдереем. И мой вопрос здесь состоял в том, как я могу сделать, если сегодняшняя дата была между датами, чтобы активировать форму. Я решил проблему следующим образом:

  • Моя задача 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 %}

Если кто-то думает, что есть лучший способ, он может предложить мне, но у меня пока будет этот ответ.

...