TypeError: первый аргумент должен вызываться при импорте планировщика в мой файл views.py django? - PullRequest
0 голосов
/ 04 сентября 2018

Я использую Django 1.11. Я хочу использовать планировщик в своем приложении для запуска сценария один раз в день.

Это мой файл view.py

from __future__ import print_function
from django.shortcuts import render
from django.utils import timezone
from django.http import HttpResponse
from datetime import datetime, timedelta
import requests
import schedule
import time


def republic(request):
    return HttpResponse("<h1>Success Hindustan</h1>")


def indiatv(request):
    return HttpResponse("<h1>Success Hindustan</h1>")

def ndtv(request):
    return HttpResponse("<h1>Success NDTV</h1>")


schedule.every().day.at("17:19").do(republic(requests))
schedule.every().day.at("17:19").do(indiatv(requests))
schedule.every().day.at("17:19").do(ndtv(requests))

while 1:
    schedule.run_pending()
    time.sleep(1)

Когда я запускаю сервер, я получаю следующую ошибку

 File "/home/imsaiful/PiroProject/pironews/feed/urls.py", line 2, in <module>
    from . import views
  File "/home/imsaiful/PiroProject/pironews/feed/views.py", line 230, in <module>
    schedule.every().day.at("17:19").do(republic(requests))
  File "/home/imsaiful/anaconda3/lib/python3.6/site-packages/schedule/__init__.py", line 385, in do
    self.job_func = functools.partial(job_func, *args, **kwargs)
TypeError: the first argument must be callable

Но когда я удаляю строки планировщика, тогда приложение работает правильно.

Ответы [ 3 ]

0 голосов
/ 04 сентября 2018

республика (запросы) вернет HttpResponse,

так что исполнение будет

schedule.every().day.at("17:19").do(HttpResponse)

внутри do метода вы должны упомянуть функцию, а не экземпляр класса. Вы можете использовать один из следующих

решение 1:

schedule.every().day.at("17:19").do(lambda: republic(requests))

решение 2.

schedule.every().day.at("17:19").do(republic, requests)

решение 3.

import functools
schedule.every().day.at("17:19").do(functools.partial(republic, requests))
0 голосов
/ 04 сентября 2018

Исправление вызова по расписанию

Письмо:

schedule.every().day.at("17:19").do(<b>republic(requests)</b>)
schedule.every().day.at("17:19").do(<b>republic(requests)</b>)
schedule.every().day.at("17:19").do(<b>republic(requests)</b>)

Вы планируете результат из republic(request) как задание, а не " вызов republic с requests как задание ".

Функция do(job_func, *args, **kwargs) [schedule-doc] , однако, позволяет предоставлять параметры, вы предоставляете эти после ссылку на задание, поэтому:

schedule.every().day.at("17:19").do(<b>republic, requests</b>)
schedule.every().day.at("17:19").do(<b>republic, requests</b>)
schedule.every().day.at("17:19").do(<b>republic, requests</b>)

Запуск планировщика в определенном потоке

Вы не можете запустить планировщик таким образом в Django, так как это будет означать, что вы продолжаете выполнять команду, когда загружает файл. Таким образом, загрузка файла никогда не прекратится, и, следовательно, сервер никогда не запустится.

Вы можете запустить планировщик асинхронно, используя:

from threading import Thread
from __future__ import print_function
from django.shortcuts import render
from django.utils import timezone
from django.http import HttpResponse
from datetime import datetime, timedelta
import requests
import schedule
import time


def republic(request):
    return HttpResponse("<h1>Success Hindustan</h1>")

schedule.every().day.at("17:19").do(republic, requests)
schedule.every().day.at("17:19").do(republic, requests)
schedule.every().day.at("17:19").do(republic, requests)

class SchedulerThread(Thread):
     @classmethod
     def run(cls):
         while True:
             schedule.run_pending()
             time.sleep(interval)

ScheduleThread().start()

Наконец, обратите внимание, что requests является не a HttpRequest объектом, поэтому вы должны писать свои функции не как представления, а как «ванильные» функции, выполняющие определенную работу.

0 голосов
/ 04 сентября 2018

на основе расписания . Job.do , вы должны передавать аргументы после функции:

schedule.every().day.at("17:19").do(republic, requests)
schedule.every().day.at("17:19").do(indiatv, requests)
schedule.every().day.at("17:19").do(ndtv, requests)

do (job_func, * args, ** kwargs)

Указывает job_func, который должен вызываться при каждом запуске задания. Все дополнительные аргументы передаются в job_func при выполнении задания.

...