Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unify Python Pyramid views for handling Ajax/html form POSTs

I have some HTML forms in my Python Pyramid application. I'd like them to work via AJAX when JavaScript is enabled and when JavaScript is disabled. Now I use different views for AJAX and normal form posts, but the code seems almost the same for these functions, except response. I use view class like this (class body):

def ajax_ok(self, msg):
    return Response(body=msg)

def ajax_error(self, msg):
    return HTTPInternalServerError(body=msg)

@action(xhr=True, renderer='json', name='ftp')
def ftp_ajax(self):
    log.debug('View: %s', 'ftp (ajax)')
    if 'form.submitted' in self.params:
        try:
            self.config.save(self.params)
        except:
            return self.ajax_error('some error')
        else:
            return self.ajax_ok('ok')

@action()
def ftp(self):
    if 'form.submitted' in self.params:
        try:
            self.config.save(self.params)
        except:
            self.request.session.flash('error; ' + msg)
        else:
            self.request.session.flash('success; ' + msg)
    return {'content': render('templates/ftp.pt', {'ftp':
                                                    self.config.ftp})} 

I need to handle error if any and show them in html. Maybe I should use finished_callback or my own renderer which will send different response for different request type??

like image 522
marcinpz Avatar asked Oct 07 '22 08:10

marcinpz


1 Answers

You could do something like that:

@action(name='ftp', renderer='templates/ftp.pt')
@action(xhr=True, renderer='json', name='ftp')
def ftp_ajax(self):
    log.debug('View: %s', 'ftp (ajax)')

    # CODE

    if request.is_xhr:
        return JSON
    else:
        return something for template

But if you do really great you could have something like that:

@action(name='ftp', renderer='templates/ftp.pt')
@action(xhr=True, renderer='json', name='ftp')
def ftp_ajax(self):
    log.debug('View: %s', 'ftp (ajax)')
    my_values = dict()

    # Code

    return my_values

but to be honest in your current code, the code isn't very similar since in you don't return the same thing and in one case, you push to flash some infos and in the second you return some things.

In that case, it's better to keep thing separated than to merge everything together. But if you can separate and return the same data, you can stack @action together.

like image 106
Loïc Faure-Lacroix Avatar answered Oct 12 '22 23:10

Loïc Faure-Lacroix