Django搜索表单未渲染及提交跳转异常求助
Hey there! Let's tackle those two problems you're having with your search form step by step.
Problem 1: Form isn't rendering on the index page
First up, the form not showing up on your index.html (which inherits layout.html). Here's what's going wrong and how to fix it:
- Your index view isn't passing the form to the template: Right now, you only create the
SearchSiteform instance in yoursearchview, but yourindexview doesn't include it in its context. So whenindex.htmlrenderslayout.html,{{ form }}is empty. - The
searchview has an undefined variable: You're includingquery_matchesin your context, but this variable isn't defined anywhere in thesearchfunction—this would throw an error and prevent the page from loading entirely.
Fixes:
- Update your
indexview to pass the form:def index(request): # Keep your existing index logic here, then add the form form = SearchSite() context = { # Your existing context variables (like entries, etc.) "form": form } return render(request, "encyclopedia/index.html", context) - Fix the undefined
query_matchesinsearchview:
Either define it (start with an empty list until you add search logic) or remove it temporarily:def search(request): form = SearchSite() query_matches = [] # Define the variable to avoid errors context = {"form": form, "query_matches": query_matches} return render(request, "encyclopedia/layout.html", context)
Problem 2: CSRF token in URL after submission + incorrect page redirect
This happens because of two issues with your form setup:
- You're using CSRF token with a GET request: CSRF tokens are only needed for POST requests. When you submit a GET form, all form fields (including the CSRF token) get appended to the URL, which is not what we want.
- Your
searchview isn't handling the submitted query: Right now it just renders the form again instead of processing the search input.
Fixes:
Remove the CSRF token from your form:
Edit yourlayout.htmlform section to delete{% csrf_token %}:<form action="{% url 'site_search' %}" method="get"> {{ form.as_p }} <!-- Using as_p to properly render form fields --> <input type="submit" value="Search"> </form>Note: Using
{{ form.as_p }}will render the form fields in a cleaner, more readable way than just{{ form }}.Update the
searchview to handle the query:
Modify the view to process the GET parameters and run your search logic:def search(request): form = SearchSite(request.GET) query_matches = [] if form.is_valid(): query = form.cleaned_data['query'] # Add your actual search logic here (e.g., query your database) # Example: query_matches = Entry.objects.filter(title__icontains=query) # It's better to render a dedicated search results template instead of layout.html # Create a search.html that inherits layout.html and displays query_matches context = {"form": form, "query_matches": query_matches} return render(request, "encyclopedia/search.html", context)Tweak your form label for clarity:
Your form's label is "New Item" which doesn't match the search functionality. Update it in your form class:class SearchSite(forms.Form): query = forms.CharField(label="Search", help_text="Search for any article located on the site.")
Bonus Tip
Make sure your search.html template inherits layout.html and includes a block to display the search results. For example:
{% extends "encyclopedia/layout.html" %} {% block title %}Search Results{% endblock %} {% block body %} <h1>Search Results for "{{ form.cleaned_data.query }}"</h1> {% if query_matches %} <ul> {% for item in query_matches %} <li><a href="{% url 'wiki' item.title %}">{{ item.title }}</a></li> {% endfor %} </ul> {% else %} <p>No results found.</p> {% endif %} {% endblock %}
内容的提问来源于stack exchange,提问作者Alejandro Armas

