Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How to call management custom command execution from admin interface?

Referring to, executing management commands from code,

Is their a way to call this command execution code from the django admin interface?

I've a custom command to do some periodic update of database which has been scheduled as cron. The cron is working fine. I need to update the database manually from the admin interface whenever needed.

like image 560
Babu Avatar asked Sep 03 '12 11:09

Babu


People also ask

What does Django-admin Startproject do?

(env) $ django-admin startproject <projectname> . The dot skips the top-level project folder and creates your management app and the manage.py file right inside your current working directory. You might encounter this syntax in some online Django tutorials.

What does manage py Runserver do?

1) python manage.py runserver It means to run a emulated server on your local computer. So, after running it, you can go to localhost:8000 or 127.0. 0.1:8000. Requirements: You must run this in the ROOT of your django project where manage.py lives.


1 Answers

update: you can run any management command simply by calling the function call_command('compilemessages') from anywhere within your python code. Note: this obviously is a blocking process from the caller's perspective. With the ajax example below you can have a form of non-blocking/asynchronous user experience. Depending on the backend implementation you can take this isolation level further.

Example:

from django.core.management import call_command
call_command('compilemessages')

If the task is bound to the object currently viewed in the admin, a nice way might be to implement an extra view called by an ajax script when clicking a button. The extra view could optionally be wrapped as a celery task, e.g.

models.py

class Foo(models.Model):
    # fields...

    def my_task_init(self):
        return mark_safe("<img class='loading' src='/static/img/loading.gif' alt='loading' style='display:none;' /><a data-identifier='task_%i' class='task'><img src='/static/img/process.png' style='cursor:pointer;' /></a>") % self.id
    my_task_init.allow_tags = True
    my_task_init.short_description = _(u"Execute Task")

admin.py

class FooAdmin(admin.ModelAdmin):
    list_display = ['other_field', 'my_task_init']

    class Media:
        js = (
            'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js',
            '/static/js/admin_tasks.js',
        )

    def get_urls(self):
        urls = super(FooAdmin, self).get_urls()
        extra_urls = patterns('',
            (r'^my-task/$', self.admin_site.admin_view(self.parse_view))
        )
        return extra_urls + urls

    # optionally decorated by celery
    def task_view(self, request):
        if not request.is_ajax():
            raise Http404
        task_id = request.GET.get('task_id')
        # your logic
        return HttpResponse('Success')

admin_tasks.js

$(document).ready(function (){
   $('.task').click(function(){
       var image = $(this).find('img'),
           loading = $(this).parent().find('.loading'),
           task_id = $(this).data('identifier').replace('task_', '');
       $.ajax({
           type: "GET",
           data: ({'task_id': task_id}),
           url: "/admin/app/model/my-task/",
           beforeSend: function() {
               image.hide();
               loading.show();
           },
           statusCode: {
               200: function() {
                   loading.hide();
                   image.attr('src', '/static/img/success.png');
                   image.show();
               },
               404: function() {
                   loading.hide();
                   image.attr('src', '/static/img/error.png');
                   image.show();
               },
               500: function() {
                   loading.hide();
                   image.attr('src', '/static/img/error.png');
                   image.show();
               }
           }
       });
   });
});

If you're trying to initiate an unbound task you could just override a template element or add some html.

like image 54
Hedde van der Heide Avatar answered Sep 20 '22 17:09

Hedde van der Heide