Run custom admin command from view - django

I have a custom admin command that emails out reports. It normally runs from a cron job. What I would like to do is add a button to my web app that when clicked will cause the the admin command to run there and then rather than wait for the cron job to call it. How do I do this? Do I have to call out to a command line such as
python manage.py myadmincmd
or can I invoke the code from within a view? It seems it would be cleaner if I could do this from within a view without needing to break out to the command line.

You can use call_command:
from django.core.management import call_command
call_command('myadmincmd')

Related

How to have a Django app running on Heroku doing a scheduled job using Heroku Scheduler

I am developing a Django app running on Heroku.
In order to update my database with some data coming from a certain API service, I need to periodically run a certain script (let's say myscript).
How can I use Heroku Scheduler to do it?
As already explained here, quick and simple way to answer this question is asking yourself how would you do to run that script periodically, as if you were the scheduler yourself.
Now, the best way to run a script in your Django app at any moment, it is to create a custom management command and to run it from your command prompt when you need it, like this:
python manage.py some_custom_command
Then, if you were the scheduler, you would run that command from your command prompt at every time written in the schedule.
So, a good idea would be to make Heroku Scheduler behave the same. Thus, the aim here is to have Heroku Scheduler run python manage.py some_custom_command at scheduled times.
Here is how you can do it:
In your_app directory, create a folder management and then inside it create another folder commands and finally, inside it, create a file some_custom_command.py
So, just to be clear
your_app/management/commands/some_custom_command.py
Then, inside some_custom_command.py insert:
from django.core.management.base import BaseCommand
from your_app.path_to_myscript_file import myscript
class Command(BaseCommand):
def handle(self, *args, **options):
# Put here some script to get the data from api service and store it into your models.
myscript()
Then go on Heroku > your_app > resources
In add-ons section select Heroku Scheduler, click on it so that its window opens, then click on add job, select the time you want, insert the command python manage.py some_custom_command and save.

How to hook a debugger to a python code running via django crontab?

I have a Django based web application, some functionality of the application is scheduled to be run as a part of cron jobs using django-crontab. I want to hook a debugger so that I can inspect some odd behaviours of my code. I normally use visual studio code. Is it possible to hook a debugger, since cron jobs basically run independently apart from server?
You can put a breaking point debugger in the code using pdb or ipdb. Like this:
def some_function():
# some code
import pdb;pdb.set_trace() # or use ipdb
# rest of the code
Then in shell, run python manage.py crontab show to show cronjobs with ids, then run python manage.py crontab run <id>. It will hit the debugger, then you will hit the breaking point. Thus you can use debugger here.

how to execute the interactive commands programmatically in django-tenants

in my terminal i can execute
1)first command
python manage.py tenant_command rebuild_index
2)second command.
the terminal will ask which schema shall i execute. for that i enter my schema name called xxx
Enter Tenant Schema ('?' to list schemas): xxx
3)3rd command i need to enter y/n option extra in terminal
then i Entered Enter
This is working fine so how to achieve this in pragmatically using management call_command pragmatically in django
management.call_command('python manage.py tenant_command rebuild_index', 'xxx')
but it giving error like
File "/home/hi/venv/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 94, in call_command
raise CommandError("Unknown command: %r" % name)
CommandError: Unknown command: 'python manage.py tenant_command rebuild_index'
so please any body tell me is it possible to achieve this kind of interactive terminal commands to run pragmatically in django
You need to pass the schema name as a keyword argument called schema_name so that the tenant_command does not prompt. You also do not need to pass python manage.py.
The syntax you want is:
from django.core import management
management.call_command('tenant_command', 'rebuild_index', schema_name='xxx')
The function call_command only needs the command name, like this:
management.call_command('tenant_command', 'rebuild_index')
Try that and see if that works. Read the docs I linked as well, there are a few examples.
I solved my problem by running it in a periodic task instead of running manual rebuild index commands everytime. See code below...
from django.core import management
def hi():
management.call_command('rebuild_index',schema_name="xxx",interactive=False)

Cron Job that access django Models

What i have done?
I have written a small application in django with few models with sqlite3 as backend. Now i want to write a python code that clears the database elements based on certain condition.
Question:
How can i achieve the above requirement?
I think the cleanest way to do this is to write your own django-admin command.
You can then run the command using manage.py:
python manage.py your_command
Having a command that can be run in shell, you can easily put in into your crontab. Optionally django-admin commands can receive command line arguments, if needed.

How to run a series of manage.py commands in Django?

I have a Django project. Everytime I deploy, I need to run a series of manage.py command (such as syncdb, south migiration, fixture update).
I am getting tired of type the command line by line and therefore I wrote a python script to do these:
import subprocess
subprocess.call(['python', 'manage.py', 'syncdb'])
#Skip the detail
subprocess.call(['python', 'manage.py', 'loaddata', 'setup/fixture.xml'])
I am wondering if there is a better way to do this?
Thanks.
You can use fabric, a Python library that allows you to script remote actions. This question has some links in the accepted answer for more information on fabric and django.
You can also call management commands directly:
from django.core.management import call_command
call_command('syncdb')
call_command('loaddata', 'setup/fixture.xml')
Save that as a normal python file and execute it from your shell or as part of your deployment scripts.