2012-07-02 6 views
5

Mam kilka formularzy HTML w mojej aplikacji Pyramid Python. Chciałbym, żeby działały przez AJAX, gdy JavaScript jest włączony i gdy JavaScript jest wyłączony. Teraz używam różnych widoków dla postów AJAX i postów normalnych, ale kod wydaje się prawie taki sam dla tych funkcji, z wyjątkiem odpowiedzi. Używam widok klasę tak (ciała klasa):Jak ujednolicić widoki Pythona Pyramid do obsługi formularza Ajax/html POSTs

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})} 

muszę obsłużyć błąd, jeśli dowolny i pokazać je w html. Może powinienem użyć finished_callback lub mojego własnego mechanizmu renderującego, który wyśle ​​inną odpowiedź dla innego typu żądania ??

+0

Wygląda na to, że tylko jedna z 4 ścieżek kodu jest taka sama, więc nie jestem pewien, co chcesz skonsolidować. Powiedziałbym, że jest wystarczająco dobry, aby obsłużyć wszystkie funkcje "zapisz" w popularnym miejscu i niezależnie zarządzać błędami. –

Odpowiedz

4

Można zrobić coś takiego:

@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 

Ale jeśli zrobisz naprawdę wielki można mieć coś takiego:

@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 

ale szczerze mówiąc w swoim obecnym Kodeksie ISN kod Jest bardzo podobny, ponieważ w tobie nie zwracasz tego samego, aw jednym przypadku naciskasz, aby błyskać niektóre informacje, a w drugim zwracasz pewne rzeczy.

W takim przypadku lepiej zachować oddzielenie niż scalić wszystko razem. Ale jeśli możesz oddzielić i zwrócić te same dane, możesz ułożyć razem jeden po drugim: @action.

+0

Podoba mi się twoje rozwiązanie, ale teraz widzę, że mam 2 problemy, a drugim jest to, jak zarządzać wyjątkami w widokach (w tej samej sytuacji - podczas publikowania formularzy html i AJAX). – marcinpz

+0

Zamiast zgłaszać wyjątki lub zwracać wyjątki, możesz użyć czegoś takiego. 'dict (ok = False, message =" komunikat o błędzie ")' gdy masz błąd i 'dict (ok = True, content = dict (...))' –

+0

zwróć uwagę, że renderer JSON wyrenderuje poprawnie Obiekt, który może kontrolować, a szablon może również wykorzystywać te wartości. Jestem prawie pewien, że możesz dodać zdarzenie beforerender, które sprawdzi ok i is.xhr i wyrzuci wyjątek, jeśli będzie to potrzebne, z zawartą wiadomością. To może nie być najlepsze, ale jest to możliwe do zrobienia. –

0

Można po prostu mieć jedną metodę ftp i wewnątrz niej sprawdzić, czy request.is_xhr jest prawdziwe, aby renderować poprawny błąd/odpowiedź.