我如何通过Django中的redis来更改芹菜工人对模型对象的db值



我想创建一个带有工人的应用程序,该应用程序在后台更改模拟模型的值。首先,用户点击开始模拟,等待一段时间,点击结束模拟,然后在页面上显示由后台工作人员更改的值差(从模拟开始到结束(。主要问题是我无法完成工人的任务。我可以在模拟模型保存后联系@receiver,并正确检查模型的值,但我不能由工人更改数据库中的模型值。

该项目名为app,application-myapp。

app/myapp/models.py

from django.db import models
class Simulation(models.Model):
# changed every simul day
created_date = models.DateField(auto_now_add=True)
today = models.DateField(auto_now=False, auto_now_add=False)
status = models.BooleanField(default=False)
daemon_active = models.BooleanField(default=False)
info = models.TextField()
def get_simulation_day(self):
"""days passed after simulation firstly start"""
# sim = Simulation.objects.all().last()
return (self.today - self.created_date).days

app/myapp/views.py

def simulate(request, action):
sim = get_simulation()
if action == "disable" and sim.status == True:
sim.status = False
sim.save()
elif action == "enable" and sim.status == False:
print('view simulate ok')
sim.status = True
sim.save()
print('view simulate ok after save')
context = {
"simulations_exists": True,
"days_passed": sim.get_simulation_day(),
"simulation_today_str": (sim.today).strftime("%d %B, %Y"),
"simulation_status": sim.status
}
return render(request, "simulation_page.html", context=context)

app/myapp/tasks.py

import logging
from django.urls import reverse
from django.core.mail import send_mail
from django.contrib.auth import get_user_model
from app.celery import app
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from .models import Simulation
# import myapp.models
@app.task
def simulate_days(sim_id):
sim = Simulation.objects.get(id=sim_id)
print('nnstart in simulate_daysnn')
it = 0
while sim.status == True:
it += 1
print(f'nn {it} iter in simulate_daysnn')
sim.daemon_active = True
sim.today = sim.today + timedelta(1)
time.sleep(5)
sim.refresh_from_db() 
sim.save()
sim.refresh_from_db() 
print('nnend in simulate_daysnn')
sim.daemon_active = False
sim.save()
@receiver(post_save, sender=Simulation)
def simulation_daemon(sender, instance, created, **kwargs):
if instance.status == True and instance.daemon_active == False:
print('start simulation_daemon')
simulate_days.delay(instance.id)
print('end simulation_daemon')

在app/settings.py我使用postgres并添加redis设置

# REDIS related settings 
REDIS_HOST = 'localhost'
REDIS_PORT = '6379'
BROKER_URL = 'redis://' + REDIS_HOST + ':' + REDIS_PORT + '/0'
BROKER_TRANSPORT_OPTIONS = {'visibility_timeout': 3600} 
CELERY_RESULT_BACKEND = 'redis://' + REDIS_HOST + ':' + REDIS_PORT + '/0' 

app/celery.py

import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
app = Celery('app')
app.config_from_object('django.conf:settings')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

在启动服务器之前,我首先设置了redis,然后设置了芹菜,它按预期工作。对于redi,我在控制台中键入:

redis-server

我得到:

[14604] 20 Nov 23:12:55 - DB 0: 4 keys (1 volatile) in 8 slots HT.
[14604] 20 Nov 23:12:55 - 11 clients connected (0 slaves), 1280840 bytes in use

芹菜:

celery worker -A app --loglevel=debug --concurrency=4

在输出中,我得到

[2019-11-20 23:12:03,182: DEBUG/MainProcess] Timer wake-up! Next ETA 1.0 secs.
[2019-11-20 23:12:04,184: DEBUG/MainProcess] Timer wake-up! Next ETA 1.0 secs

我认为您的问题是在您的任务中更改为today的值之后立即使用refresh_from_db引起的。这将导致任何更改的值都被数据库中保存的内容覆盖。在这种情况下,它永远不会允许更改today值。

sim.today = sim.today + timedelta(1)
time.sleep(5)
sim.refresh_from_db() # This will overwrite the `today` value you set in the line above
sim.save() # This will just save the old value that was already in the DB

相关内容

  • 没有找到相关文章

最新更新