Send Weekly Email Notifications to Users regarding any changes in data - django

What are ways to send automatic weekly email notifications to users upon any update or changes in the data in a django project ?

I'll describe the simplest solution I'm aware of. There are also much, much more sophisticated approaches to this problem.
Fundamentally, you need three things:
A task runner (I recommend configuring cron jobs with django-kronos)
An SMTP provider (I recommend Mailgun, which is super simple to set up with Django and gives you some test credits out of the box).
Email templates (write yourself & render to string w/ Django -- Mailgun has some good open source templates as well on their blog)
Example: django-kronos provides decorators for registering functions as cron jobs (this assumes your web server is Linux-based). These jobs can be installed as part of your deploy process from the command line:
./manage.py installtasks
For kronos to find tasks, they must be located in cron.py files inside of your apps.
# myapp/cron.py
import kronos
from django.contrib.auth.models import user
from myapp.services import check_for_changes, notify_user_of_change
# Register cron job to run once a week (every Sunday) at midnight
#kronos.register('0 0 * * 0')
def notify_about_changes():
"""Sets up a cron job and runs this service function once a day.
Installed With:
``./manage.py installtasks``
"""
all_my_users = User.objects.all()
for user in all_my_users:
changes = check_for_changes(user)
for change in changes:
notify_user_of_change(user, change)
Note that it's a good practice to keep your task function as "thin" as possible. In your case, you're (a) checking for changes, then (b) notifying about each change. These could each be a function that accepts a user instance as a param, or they could be model methods. In any case, the hard work should be handled elsewhere.

This is a very broad question, so unfortunately the answer is going to be broad as well. The general workflow you're looking for probably starts off with a Signal which you can set up to be activated on update of data.
That signal would then store data about the changes and then use one of many different email options to send email. You could use either built-in Django emails, or use a 3rd party API such as django-mailchimp.
Hopefully this gets you headed in the right direction.

Related

Options for running on user demand asynchronous / background tasks in Django?

My Django app generates a complex report that can take upto 5 minutes to create. Therefore it runs once a night using a scheduled management command.
That's been ok, except I now want the user to be able to select the date range for the report, which means the report needs to be created while the user waits.
What are my options for running the tast in the background? So far I've found these:
Celery - might work but is complex
django-background-tasks looks like the right tool for the job but hasn't been updated for years, last supported Django is 2.2
The report/background task could be generated by AWS Lambda, basically in a microservice. Django calls the Microservice which can execute the background task then call the Django app back once finished. This is what I did last time but not sure it would work now as I'd need to send the microservice 10mb of data to process.
Use subprocess.popen which someone here said worked for them but other reports say it doesn't work from Django.
EDIT: Looks like Django 3.1 onwards supports ASync views and may be the simple solution for this.

Execute function at special time using Django

I write task manager, and i want to create bot, which must send message to user (maybe user's email or social account).
I want to user can be able choose task and set time, when bot should send message to him.
My proble is that I don't know what i can user for it, I use django framework, and now i think that celery can help me with it.
Celery might be a bit heavy to start with.
You can try the django_cron to schedule your email tasks or other cron jobs that need to run at a specific time.
It's quite easy to set up following its documentation.

django how to automate functions inside views.py file

Well, this question will surely make the delights of the downvotes brigade and may be tagged as" too broad etc", but it is not!, but precisely because it requires "general" knowledge of how things work, I cannot find an answer in the books I have to ask it.
Having my Django application, yes, I can make it interactive by means of the MVC flow. The issue that I have is when I have methods that are not in connection with an html page (that the user sees) but are methods that are supposed to be running constantly in the background. For example, just to illustrate, imagine a code snippet that queries a DB and sends an email with news every 2 hours. It is just not doing anything because I dont know how to "wake that code snippet up".
I dont have that problem if I am writing a desktop application in just python without Django. If I right click and say, run this file, the code will running in the background alright.
Yes, naturally I have heard of cron jobs etc, but so far I see that you can cron-tab a file but how do I crontab a method inside views.py? but I suppose that is not either the way to go. I am find that you downvote it, as long as I get an answer.
thank you
I've been using a combination of commands and cron jobs for that purpose.
Write your command, set up your cronjob:
30 3 * * * /home/ubuntu/project/env/bin/python /home/ubuntu/project/manage.py command_name
Profit.
If you want to execute periodic tasks in Django, then there are multiple options.
Using Crontab.
There are multiple Django crontab apps are available. (django-crontab)
You just need to add the cron function in your settings file.
CRONJOBS = [
('*/5 * * * *', 'myapp.cron.my_scheduler')
]
cron.py
from myapp.views import send_email
def my_scheduler():
# add logic
send_email()
Using Celery Beat
I personally prefer Celery over crontab . You can check it here

Alternative to django-celery to perform asynchronous task in Django?

In my admin I have a form allowing to upload a file to fill the DB.
Parsing and filling the DB take a long time, so I'd like to do it asynchronously.
As recommended by several SO users I tried to install python-celery, but I can't manage to do it (I'm on Webfaction).
Is there any simple, easy-to-install alternative?
If webfaction supports cron jobs you can create your own pseudo broker. You could save your long running tasks to the db and in a 'tasks' table, this would allow you to return a response to the user instantaneously. Then there could be a cron that goes through very frequently and looks for uncompleteled tasks and processes them.
I believe this is what django mailer does
https://github.com/jtauber/django-mailer/
https://stackoverflow.com/a/1419640/594589
Try Gearman along with it's python client library
It's very easy to setup and run gearman. Try few examples.

Rather than using crontab, can Django execute something automatically at a predefined time

How to make Django execute something automatically at a particular time.?
For example, my django application has to ftp upload to remote servers at pre defined times. The ftp server addresses, usernames, passwords, time, day and frequency has been defined in a django model.
I want to run a file upload automatically based on the values stored in the model.
One way to do is to write a python script and add it to the crontab. This script runs every minute and keeps an eye on the time values defined in the model.
Other thing that I can roughly think of is maybe django signals. I'm not sure if they can handle this issue. Is there a way to generate signals at predefined times (Haven't read indepth about them yet).
Just for the record - there is also celery which allows to schedule messages for the future dispatch. It's, however, a different beast than cron, as it requires/uses RabbitMQ and is meant for message queues.
I have been thinking about this recently and have found django-cron which seems as though it would do what you want.
Edit: Also if you are not specifically looking for Django based solution, I have recently used scheduler.py, which is a small single file script which works well and is simple to use.
I've had really good experiences with django-chronograph.
You need to set one crontab task: to call the chronograph python management command, which then runs other custom management commands, based on an admin-tweakable schedule
The problem you're describing is best solved using cron, not Django directly. Since it seems that you need to store data about your ftp uploads in your database (using Django to access it for logs or graphs or whatever), you can make a python script that uses Django which runs via cron.
James Bennett wrote a great article on how to do this which you can read in full here: http://www.b-list.org/weblog/2007/sep/22/standalone-django-scripts/
The main gist of it is that, you can write standalone django scripts that cron can launch and run periodically, and these scripts can fully utilize your Django database, models, and anything else they want to. This gives you the flexibility to run whatever code you need and populate your database, while not trying to make Django do something it wasn't meant to do (Django is a web framework, and is event-driven, not time-driven).
Best of luck!