2015-10-23 7 views
5

Mam formularz, po wprowadzeniu informacji, na podstawie informacji, filtruje bazę danych i wykonuje pewne obliczenia, a następnie wyświetla wynik przekierowanego adresu URL.django - dlaczego po przekierowaniu wyświetla się formularz "Brak"

Rzeczywiście mogę przekierować do innego adresu URL i pomyślnie wyświetlić wynik. Ale problem polega na tym, że nie może wyświetlać żadnych danych przesłanych przez użytkownika, po prostu nie pokazuje niczego dla każdego pola, a wynik nie jest oparty na dopasowanym zapytaniu. Powiedzmy, że suma, to po prostu podsumowanie wszystkich kolumn w bazie danych, bez użycia przefiltrowanego wyniku.

Podejrzewam, że zestaw zapytań nie przekazuje przefiltrowanego wyniku do def get_context_data, dlatego zestaw zapytań w get_context_data nie działa.

Naprawdę dziękuję bardzo, jeśli rozwiążesz moje wątpliwości.

(zrobiłem wersję EDIT oparciu o sugestię, aby połączyć 2 Ćwiczenia, nadzieję, że ktoś może skorygować tę wersję EDIT dzięki)

enter image description here

urls.py

url(r'^result_list/$',ResultView.as_view(),name='result'), 
url(r'^input/$',InputFormView.as_view(),name='input'), 

views.py

class InputFormView(request): 
#class InputFormView(FormView): 
    template_name = 'inputform.html' 
    form_class = InputForm 

    response = HttpResponse('result') 
    request_form_data = request.POST #you need to sanitize/clear this data 
    response.set_cookie('form_data', request_form_data) 

#redirect to result page with submitted form information 

    def get_success_url(self): 
     return ''.join(
     [ 
      reverse('result'), 
      '?company=',self.request.POST.get('company'), <--do I need to change "POST" into "USER"? 
      '&region=',self.request.POST.get('region') 
     ] 
     ) 

#class ResultView(ListView): 
class ResultView(request): 
    context_object_name = 'result_list' 
    template_name = 'result_list.html' 
    model = Result 

    def get_context_data(self, **kwargs): 
     context = super(ResultView, self).get_context_data(**kwargs) 
     context["sales"] = self.get_queryset().aggregate(Sum('sales')) 
     context["company"] = self.request.POST.get("company") 
     context["region"] = self.request.POST.get("region") 

     return context 

    def get_queryset(self): 
     if self.request.method == 'POST': 
      form = InputForm(self.request.POST) 
      if form.is_valid(): 
       company = form.cleaned_data['company'] 
       region = form.cleaned_data['region'] 

       queryset=Result.objects.filter(region=region) 
       return queryset 
     return Result.objects.all() 

    if request.COOKIES.has_key('form_data'): 
     value = request.COOKIES['form_data'] #this data also should be sanitized 

html

<div class="basicinfo">   <!--Entry Form information submitted by user--> 
    <table border="1" cellpadding="1"> 
    <tr> 
     <td align="left">Company</td> 
     <td>{{ company }}</td> 
    </tr> 
    <tr> 
     <td align="left">Region</td> 
     <td>{{ region }}</td> 
    </tr> 
    </table> 
</div>  

<!--Showing the filtered result in database--> 
<td><table border="0" cellspacing="10" cellpadding="10"> 
<tr><b>Sales</b></tr> 
<td bgcolor="#F0F0F0"> {{ sales.sales__sum }}</td> 

</tr> 
<tr><b>Employee</b></tr> 
<tr> 
<td bgcolor="#F0F0F0"> {{ employee.employee__sum }}</td> 

</table> 

Edit- łącząc widoki klasa 2

import urllib 

#@csrf_exempt 

class ResultView(ListView): 
    context_object_name = 'result_list' 
    template_name = 'result_list.html' 
    model = Result 

    def get_queryset(self): 
     form = InputForm(self.request.GET) 
     if form.is_valid(): 
      company = form.cleaned_data['company'] 
      region = form.cleaned_data['region']   
      queryset=Result.objects.filter(region=region) 
      return queryset 
     return Result.objects.all() 

    def get_success_url(self): 
     params = { 
      'company': self.request.POST.get('company'), 
      'region': self.request.POST.get('region') 
     } 
     return ''.join([reverse('result'), '?', urllib.urlencode(params.items())]) 

    def get_context_data(self,**kwargs): 
      context = super(ResultView, self).get_context_data(**kwargs) 
      context["sales"] = self.get_queryset().aggregate(Sum('sales'))   
      context["company"] = self.request.GET.get("company") 
      context["region"] = self.request.GET.get("region")  
      return context 

** Edit- urls.py **

url(r'^result_list/$',ResultView.as_view(),name='result'),----for the result page 
url(r'^input/$',result.views.get_success_url,name='input') -----for the form, I am not sure if this line correct or not? 
+2

** Co ** dokładnie pokazuje Brak? –

+0

Wierzę, że tak właśnie się dzieje - Zakładasz, że dane mają być w kontekście 'POST', ale kiedy przekierowujesz na inną stronę, nie jest to już" POST "- dlatego tracisz dane w kontekście. Jednym ze sposobów podejścia do tego byłoby wysłanie argumentów POST jako kwargs do przekierowanego widoku. – karthikr

+0

hi @ Daniel Roseman, na przekierowanej stronie, wartość "firma" i "region" pokazuje "Brak" –

Odpowiedz

3

Twój kod powinien działać, jeśli zmienić metodę get_queryset do:

def get_queryset(self): 
    # You are sending GET params here, not POST 
    form = InputForm(self.request.GET) 
    if form.is_valid(): 
     company = form.cleaned_data['company'] 
     region = form.cleaned_data['region'] 

     queryset=Result.objects.filter(region=region) 
     return queryset 
    return Result.objects.all() 

i metoda get_context_data do:

def get_context_data(self, **kwargs): 
    context = super(ResultView, self).get_context_data(**kwargs) 
    context["sales"] = self.get_queryset().aggregate(Sum('sales')) 
    # Your variables are in GET, not POST 
    context["company"] = self.request.GET.get("company") 
    context["region"] = self.request.GET.get("region") 
    return context 

Powiedział, że kod może zrobić z jakiegoś refaktoringu. Czy naprawdę potrzebujesz FormView, który akceptuje żądanie POST? Zamiast tego możesz mieć formularz, który przesyła bezpośrednio przez GET do widoku wyników.

Przy obecnym podejściu faktycznie przetwarzasz formularz dwukrotnie - raz w każdym z widoków.

Edycja: również sposób, w jaki generujesz przekierowanie, nie jest bezpieczny. Powinieneś więc coś takiego zamiast tego:

import urllib 
def get_success_url(self): 
    params = { 
     'company': self.request.POST.get('company'), 
     'region': self.request.POST.get('region') 
    } 

    return ''.join([reverse('result'), '?', urllib.urlencode(params.items())]) 
+0

Hi @solarissmoke, jest pewien błąd dotyczący "return" .join ([reverse ('result "),"? ", urllib.urlencode (params)])". Aktualizuję traceback w poście, dzięki. –

+0

Edytowałem odpowiedź - spróbuj 'urllib.urlencode (params.items())'. – solarissmoke

+0

Witam @solarissmoke, ponieważ mam 2 adresy URL osobno dla formularza i wyniku, więc zrobiłem także 2 osobny widok klasy. W oparciu o twoją sugestię, masz na myśli usunięcie klasy InputFormView, przesunięcie części def get_success_url do ResultView (request), prawda? Proszę, popraw mnie, jeśli się mylę, dzięki. –

1

Jeśli się żądanie POST , a następnie przekierowujesz użytkownika, pojawi się następne żądanie pusty POST (od teraz to kolejne żądanie). Nie jest to więc zaskakujące zachowanie. Jeśli chcesz zapisać te dane między sesjami, możesz je zapisać na przykład w sesji użytkownika.

Można modyfikować niektóre z was poglądy (co czyni przekierować, wierzę) dodając ten kod:

Ustawianie cookie:

def your_view_which_makes_redirect(request): 
    #.. here is your code 
    response = HttpResponse('blah') 
    request_form_data = request.POST #you need to sanitize/clear this data 
    response.set_cookie('form_data', request_form_data) 

Pierwsze cookies:

def your_view_which_renders_page_after_rediret(request): 
    if request.COOKIES.has_key('form_data'): 
    value = request.COOKIES['form_data'] #this data also should be sanitized 

1) Możesz również przenieść nazwę tego pliku cookie do ustawień, ponieważ teraz są one na stałe i teraz jest to bardzo dobra praktyka. Coś jak ustawienia.SAVED_FORM_NAME_COOIKE_TOKEN 2) Musisz również odkażać dane z request.POST i request.COOKIES, ponieważ użytkownik może umieścić tam pewne złośliwe dane (SQL injection itd.).

+0

Hi @ Paul, czy możesz zrobić przykład na ten temat? Jestem trochę zdezorientowany ... –

+0

dziękuję ~ Nie jestem pewien, czy rozumiem cię poprawnie, dlatego zaktualizowałem views.py tak, jak sugerujesz, zwraca błąd, jak "nazwa nie jest zdefiniowana", czy możesz mi pomóc spojrzeć lub edytuj na tha t bezpośrednio? –

+0

@ Elena, czy mógłbyś pokazać kod z widoku, w którym wykonujesz przekierowanie? – Paul