2017-08-31 1 views
2

J'essaie de créer un formulaire de recherche simple dans Django. Voici ce que j'ai jusqu'à présent:NoReverseMatch: Impossible de passer le paramètre du modèle à l'affichage.

forme

:

<form action="{% url 'search_pub' pub_name=pub_name %}" method="get"> 
    Publication name: <input type="text" id="pub_name" name="pub_name" value="herald"> 
    <input type="submit" value="Search"> 
</form> 

urls.py

url(r'^search/$', views.search, name='search'), 
url(r'^results/(?P<pub_name>[\w]+)/$', views.search_pub, name='search_pub'), 

views.py

def search(request): 
    return render(request, 'urlapp/search.html') 

def search_pub(request, pub_name): 
    pubs = Publication.objects.all().filter(title__icontains=pub_name) 
    return render(request, 'app/results.html', { 
     'publications': pubs 
    }) 

models.py

class Publication(models.Model): 
    title = models.CharField(max_length=30) 

je reçois l'erreur suivante quand j'ouvre la page de recherche http://localhost:8000/search/:

NoReverseMatch at /search/ 
Reverse for 'search_pub' with keyword arguments '{'pub_name': ''}' not found. 1 pattern(s) tried: ['results/(?P<pub_name>[\\w]+)/$'] 

J'ai vérifié que le regex est valide à l'aide du site pythex.

Si je vais à l'URL: http://localhost:8000/results/herald, j'obtiens les bons résultats.

Qu'est-ce qui me manque?

+0

Valeur de 'pub_name' dans le modèle semble vide? – Rohan

+0

Oui, je ne suis pas capable de comprendre pourquoi. – Animesh

Répondre

1

Vous ne pouvez pas utiliser les variables GET comme des arguments d'URL. De plus, les valeurs {% url ... sont calculées côté serveur, donc vous ne pouvez pas les modifier dynamiquement dans un formulaire HTML. Je ferais ce qui suit:

D'abord, modifiez la ligne suivante

url(r'^results/(?P<pub_name>[\w]+)/$', views.search_pub, name='search_pub'), 

à

url(r'^results/$', views.search_pub, name='search_pub'), 

Ensuite, modifiez votre code en vue de ressembler à ceci:

def search_pub(request):     # Remove pub_name from method signature 
    pub_name = request.GET.get('pub_name') # ...and fetch it from GET dict instead 
    ... 

Enfin , changez votre form tag:

<form action="{% url 'search_pub' %}" method="get"> 

Notez que dorénavant vos URL seront sous la forme suivante:

http://localhost:8000/results?pub_name=herald 

Mise à jour:

Si vous voulez vraiment avoir la valeur dans l'URL, vous pouvez rediriger d'une à l'autre:

Gardez les deux URL dans vos urls.py avec différents noms:

url(r'^results/(?P<pub_name>[\w]+)/$', views.search_pub, name='search_pub_clean'), 
url(r'^results/$', views.search_pub, name='search_pub'), 

et le code de la vue:

from django.shortcuts import redirect 
def search_pub(request, pub_name=None): 
    if pub_name is None: 
     return redirect('search_pub_clean', pub_name=request.GET.get('pub_name')) 
    ... 
+0

C'est la méthode de la chaîne de requête, que j'ai déjà essayée. Mais je cherche à avoir une URL propre comme '/ results/pubname/year'. Dois-je avoir un modèle et un formulaire séparés uniquement pour la page de recherche pour accomplir ceci? – Animesh

+0

Vous n'avez pas besoin de. Vous pouvez avoir deux configurations d'URL et les rediriger de l'une à l'autre. Voir ma réponse mise à jour. – Selcuk

+1

C'est beaucoup mieux. Je vais maintenant avoir une redirection à traiter. :) – Animesh