Search code examples
djangodjango-modelsdjango-viewsdjango-formsdjango-templates

How to use form data to render a certain view.py function in Django


I am working on this harvardCS50 project where I have to redirect the user to the article page if their search query meets the dictionary key. I have stored the articles as 'text' and headings as 'head in the dictionary.

data = {
    "textone": {"head": "Title one", "text": "This will be text ONE."},
    "texttwo": {"head": "Title two", "text": "This will be text TWO."}
}

I was able to make article links that render the requested data, but I have not been able to do it through the form data. If the user input meets the key in my dictionary, the html should render the data based on that.

<head>
        <title>{% block title %} {% endblock %}</title>
    </head>
    <body>
        <nav>
            <form action="" method="GET">
                <input type="text" name="q">
                <input type="submit">
            </form>
            <ul>
                {% for key, value in data.items %}
                <a href="{% url 'wikiApp:entry' key %}"><li> {{ value.head }} </li></a>
                {% endfor %}
            </ul>
        </nav>
        {% block body %}
        
        {% endblock %}
</body>

Following is my views.py:

def intro(request):
    context={"data": data}
    return render(request, 'wiki/layout.html', context=context)

def title(request, entry):
    for name in data:
        if name == entry:
            return render(request, 'wiki/content.html', {
                "head": data[name]['head'],
                "text": data[name]['text'],
                "data": data
            })
    return render(request, 'wiki/404.html')

def search(request):
    query_dict = request.GET
    query = query_dict.get("q")
    article = data.get(query)
    return render(request, 'wiki/content.html', {
        "head": article['head'],
        "text": article['text']
    })

And the urls.py:

app_name = "wikiApp"

urlpatterns = [
    path('', views.intro, name='intro'),
    path('', views.search, name='search'),
    path('<str:entry>', views.title, name='entry')
]

It is to be noted that I have not created static html pages for different articles and the idea is to render each page based on the user's request. I have read tons of stuff and tried a lot of different approaches but I think I am missing something very obvious.


Solution

  • I was finally able to figure out the problem(s) in my code. What I didn't know was, that if there are two similar paths, Django proceeds with the first that meets the conditions. Therefore, I updated the 'urls.py' as follows.

    You can read more at Django documentation - URL dispatcher

    app_name = "wikiApp"
    
    urlpatterns = [
        path('', views.intro, name='intro'),
        path('article/', views.search, name='search'),
        path('article/<str:entry>', views.title, name='entry')
    ]
    

    Secondly, I added a URL value to the action attribute of my form's template file, that calls the path named 'search' from urls.py which calls the view function that processes the form data.

    <form action="{% url 'wikiApp:search' %}" method="GET">
       <input type="text" name="q">
       <input type="submit">
    </form>
    

    Lastly, I updated my view function to fetch the dictionary data, based on the head's value instead of the dictionary's key.

    def search(request):
        query_dict = request.GET
        query = query_dict.get("q")
        for key, value in data.items():
            if value['head'] == query:
                context={"head": value['head'], "text": value['text'], "data": data}
                return render(request, 'wiki/content.html', context=context)
        return render(request, 'wiki/404.html')
    
    data = {
        "textone": {"head": "Title one", "text": "This will be text ONE."},
        "texttwo": {"head": "Title two", "text": "This will be text TWO."}
    }
    

    The end.