Estoy usando Django para desarrollar un sitio web. El sitio web está diseñado para buscar información almacenada en una base de datos MySQL.

Este es el flujo básico actual del sitio web. 1) index.html: tiene un formulario para seleccionar una opción 2) de acuerdo con la opción, los usuarios lo redireccionarán a search.html (incluir un formulario) 3) una vez que el usuario proporcione los criterios, el resultado se mostrará en reply.html

En mi views.py, tengo dos funciones.

from django.shortcuts import render
from website.models import WebsiteRepository
from .forms import SearchForm
from .forms import SelectTypeForm


def Search(request):
if request.method == 'POST':
    #do something
    return render(request, 'reply.html', {'env_dict':env_dict})
else:
    #do something
    return render(request, 'search.html', context = context)

def index(request):

if request.method =='POST':
   #do something
   return render(request, 'search.html', context = context) 
else:
    #do something
    return render(request, 'index.html', context= context)  

Cuando voy a la página index.html, puedo seleccionar una opción y me dirigirá a search.html. Después, completo el formulario allí y lo envío, no me dará la página Reply.html.

Tengo la sensación de que podría hacer que esto funcione cambiando urls.py.

from django.urls import path
from website import views


 urlpatterns = [
      path('', views.index, name='index'),
      #path('search/', view.Search, name ='Search')

 ]

Traté de buscarlo en Google. Pero son demasiados detalles y estoy un poco perdido.

¿Alguno de ustedes sabe cómo lograr esto?

Gracias

Search.html

{% extends "base_generic.html" %}
{% block content %}

   <h3>Welcome to search information Repository</h3>
   <form method="post">
   {% csrf_token %}
   {{form.as_p}}
   <button type = 'submit'>submit</button>
   </form>

{% endblock %} 

Index.html

{% block content %}
   <h3>Welcome to information Repository</h3>
       <form method="post">
       {% csrf_token %}
       {{form.as_p}}
    <button type = 'submit'>submit</button>
  </form>

Solo para aclarar más las cosas, agregaré las formas.py también

from django import forms
from .models import  WebsiteRepository

class SearchForm(forms.Form):
   websiterepository = WebsiteRepository


   env_indicators =  websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
   indicator = forms.ChoiceField(choices=env_indicators,label = 'Indicator'      )


  OPTIONS = (('2000','2000'),('2001','2001'),('2002','2002'), ('2003','2003'),('0000','0000'),)
   year = forms.ChoiceField(choices=OPTIONS)





class SelectTypeForm(forms.Form): 

      OPTIONS = (('1', 'Envirnmental Indicators'),('2','Economic Indicators'),('3','Social Indicators'),)
      types = forms.ChoiceField(choices=OPTIONS)
0
Sasha 17 oct. 2018 a las 08:20

2 respuestas

La mejor respuesta

Su código es incorrecto en muchos puntos.

Lo primero es lo primero: para una búsqueda, desea una solicitud GET, no una POST (POST es para actualizar el estado del servidor, principalmente para agregar o actualizar su base de datos). Este es el método semánticamente correcto (ya que desea OBTENER datos) y permitirá al usuario marcar la URL como favorita.

Segundo punto: no desea enviar el formulario de búsqueda a la vista de índice, sino a la vista de búsqueda. No hay necesidad de redireccionamientos, etc., solo use la etiqueta de plantilla {% url %} para completar el atributo action de su formulario (por supuesto, debe tener una URL de 'Búsqueda' en su urls.py):

<form method="get" action="{% url 'Search' %}">
   {% csrf_token %}
   {{form.as_p}}
   <button type = 'submit'>submit</button>
  </form>

Si desea tener este formulario en más de una página (que suele ser el caso de los formularios de búsqueda), use una etiqueta de inclusión que se encargará de crear un formulario de búsqueda independiente y renderizará el fragmento de la plantilla.

Luego, en su vista de búsqueda, solo desea solicitudes GET y no use dos plantillas diferentes, esto solo conducirá a una duplicación inútil.

def Search(request):
    form = SearchForm(request.GET)
    # use the form's data - if any - to get search results 
    # and put those results (even if empty) in you context 
    return render(request, 'reply.html', {'env_dict':env_dict})

Y finalmente, su formulario de búsqueda está totalmente roto:

class SearchForm(forms.Form):
   # this is totally useless
   websiterepository = WebsiteRepository

   # this will only be evaluated once at process startup, so you will
   # get stale data in production - and probably different data
   # per process, in a totally unpredictable way.
   # You need to either put this in the form's __init__ or wrap it
   # in a callable and pass this callable

   env_indicators =  websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
   indicator = forms.ChoiceField(choices=env_indicators,label = 'Indicator'      )



  # are you going to manually add a new year choice every year ???
  OPTIONS = (('2000','2000'),('2001','2001'),('2002','2002'), ('2003','2003'),('0000','0000'),)
   year = forms.ChoiceField(choices=OPTIONS)

Para los "indicadores" ChoiceField, desea algo como:

def get_indicators_choices():
    return Websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')

class SearchForm(forms.Form):
   # IMPORTANT  : we are NOT calling the function here, just
   # passing it (python functions are objects) to the field, which
   # will call it everytime the form is instanciated, so you don't
   # have stale data
   indicator = forms.ChoiceField(
        choices=get_indicator_choices, 
        label='Indicator')

Como última nota: sea coherente con sus nombres (es decir, ¿por qué nombrar una vista en todas las minúsculas (index) y poner en mayúscula la otra (Search)? Cualquiera que sea la convención que elija (sugiero encarecidamente respetando pep8 aquí), al menos apégate a él durante todo el proyecto.

0
bruno desthuilliers 17 oct. 2018 a las 09:00

El problema es que el código no redirige a /search, sino que muestra search.html después de la publicación desde index.html .

Intenta hacer como

Views.py-

#your code 

def index(request):
   #do something
   if request.method == 'POST':
      return redirect('Search')
   else:
      #render index.html

def search(request):
   #do something
   if request.method == 'POST':
      #render reply.html
   else:
      #render search.html

Otra forma de lograr esto es si especifica acción en su formulario para que el formulario publique en /search.

Search.html

<form method="post" action="/search">
   {% csrf_token %}
   {{form.as_p}}
   <button type = 'submit'>submit</button>
   </form>
-1
aquaman 17 oct. 2018 a las 06:10