I have a model that gets the day and time of week when an event should always occur. Also, the number of days before the event that people will be able to attend.
def validate_only_one(obj):
model = obj.__class__
if model.objects.count() > 0 and obj.id != model.objects.get().id:
raise ValidationError("Você só pode adicionar um evento") # You can add only one schedule
class ModelPresenca(models.Model):
DIAS = (
# The days are in Portuguese
('Domingo', 'Domingo'),
('Segunda', 'Segunda'),
('Terça', 'Terça'),
('Quarta', 'Quarta'),
('Quinta', 'Quinta'),
('Sexta', 'Sexta'),
('Sábado', 'Sábado'),
)
dia = models.CharField('Dia da Pelada', max_length=10, help_text='Escolha o dia da pelada', choices=DIAS) # day of the event
hora_pelada = models.TimeField('Horário da pelada (ex: 19:30)', help_text='Hora em que sua pelada é realizada') # hour of the event
dias_antecedencia = models.PositiveIntegerField('Dias antecedência',
default=1,
validators=[MinValueValidator(1), MaxValueValidator(6)],
help_text='Em quantos dias de antecência os peladeiros devem '
'marcar presença') # numbers of days before event
However, I don't know how to make this event repeat without requiring the user to add the same information every week. I'm thinking of the following algorithm:
def period(request):
event_data = ModelPresenca.objects.all() # I have always only one object
hour_timefield = datetime.strptime(h.hora_pelada, '%H:%M') # TimeField to string
day = event_data.dia # Day of the event
b_days = event_data.dias_antecedencia # Number of days before event
week_d = week_day(day) # week_day is a function that converts day to int
event_d = event_day(week_d, hour_timefield) # event_day is a function that returns the date of full event occur
conf_d = event_open_date(b_days, event_d) # Is a function that returns date of open to confirm
n = datetime.now()
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 (conf_d <= today) and (today < event_d):
# Show formulary to confirm presence
else:
# another thing, ie, hidden formulary
I believe that this last code block have to repeat, but I don't know to do this and I don't know if It's the best way. If anyone can help me, I appreciate.
You can use Django Celery. Celery is an asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.
Here are first steps for django celery. You could create a post_save method in your model, where you will run a asynchronous task, which will add events as you wish. Additionally there is a Celery beat which enables you creating asynchronous periodic tasks.
For example:
@app.task()
def period():
# Do your stuff here
and then in your settings file add your celery beat schedule:
CELERY_BEAT_SCHEDULE = {
'add-periodic-events': {
'task': 'my_app.my_tasks.periodic', # this is a path to your file separated by '.'
'schedule': crontab(minute=0, hour=0), # Execute daily at midnight.
},
}