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

后端 未结 1 461
星月不相逢
星月不相逢 2021-02-06 13:59

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 comm

相关标签:
1条回答
  • 2021-02-06 14:11

    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.

    0 讨论(0)
提交回复
热议问题