In this lesson, we would be discussing further uses of the views.py file other than just returning an HTML page. To do this we would be building a small app while we make a few changes to the way our current homepage is displayed.
Changes to Make
Currently, our Homepage is served from the blog app, but we should honestly leave the blog for only blog related things. Meaning we have to move our homepage out, probably to the root directory. The first thing we would do is create a folder called templates in the awesome-project directory. Second, move the home.html file to this newly created folder.
Next, go to settings.py. Around line 55, we see TEMPLATES. Inside the list of DIRS add 'templates', which is the name of the templates folder we created.
So, my line 58 looks like:
58. 'DIRS': ['templates'],
Next, we create a views.py file inside the awesome directory. and copy the content from the views.py inside the blog directory. You can go ahead and delete the function we created in the previous views.py. And make appropriate changes to the views.py inside the awesome directory.
1. from django.shortcuts import render
2.
3. # Create your views here.
4. def home(request):
5. return render(request, 'home.html')
This should be inside awesome/views.py
One more change we should make, assuming I'm not missing anything out, is to the awesome/urls.py file. Instead of having:
18. from blog import views
We now have:
18. from . import views
This means - from this directory, import views.
Save all files, run your server and make sure your home page still displays. If it does, let's move on.
Views.py
So to dive into this, we'd be adding a form to our home page that counts the number of vowels in some text. It's a good practice to highlight what would be needed. Thinking of this problem and what we have learnt so far, we would be needing:
- A form that we use to collect user input;
- A function that counts the vowels;
- A page that we return the number of vowels to.
So let us start with no. 1. Adding a form. For the sake of simplicity, we would be adding it to the homepage.
<form method="POST" action="">
<textarea name="input-stuff" rows="10" cols="30"></textarea>
<button type="submit">Check vowel count</button>
</form>
So, here's what my form looks like. Notice I have a method and action on the form tag and a name on my textarea tag. The method is POST because it's a POST request. The action is the url that should be triggered when the button is clicked. We would get back to it. Let's go create our function.
No. 2
We'd be naming our function counter. and it would look like this:
# awesome/views.py
8. def counter(request):
9. if request.method == 'POST':
10. vow = 0
11. for i in request.POST['input-stuff']:
12. if i in 'aeiou':
13. vow += 1
Most of this code might look familiar, except line 9 and line 11. Line 9 checks if the request method is a POST. A POST request is basically used when sending certain information to the server. Usually from a form. Line 11, on the other hand, is used to access the information inputted in the textarea. Remember that we named the textarea input-stuff. Well, this helps to access it. One thing we must not forget is that our function must always return something. If it doesn't we would most likely get error 500. So the question is: what do we return? Simple. A page to display the result.
No. 3
Let's create an HTML file called count in the templates directory. We would be back to what should be inside it in a few. Okay... That's a lot of things on hold.
- Action in the form tag.
- A return statement in the counter function.
- The content of the count.html file
- The url that would lead to the counter function.
Let us handle the view.py first. We need a return statement. Our return statement would return the page and a bit of extra information: the number of counted vowels. How do we do this? Well:
8. def counter(request):
9. if request.method == 'POST':
10. vow = 0
11. for i in request.POST['input-stuff']:
12. if i in 'aeiou':
13. vow += 1
14. return render(request, 'count.html', {'count': vow})
Okay. Wait a minute. We recognize that last part {'count': vow} as a python dictionary. So we could use this to pass extra information back to the page that we are also returning; in this case, the count.html page.
One thing we should also address if someone tries to visit the count.html page without going through the home page. Let's just set it to send them to the homepage. For this, we would need to import redirect.
1. from django.shortcuts import render, redirect
...
...
8. def counter(request):
9. if request.method == 'POST':
10. vow = 0
11. for i in request.POST['input-stuff']:
12. if i in 'aeiou':
13. vow += 1
14. return render(request, 'count.html', {'count': vow})
15. return redirect('home')
Line 15 gives us what we are looking for. Meaning, if the request isn't a POST request, it would not encounter the first return statement and would move to the next. The return statement on line 15 says: redirect the user to a url with the name of home. We use the url name, not the html file. Note.
Now, let us move to creating the url. Move over to your awesome/urls.py file, let's add another path.
20. urlpatterns = [
21. path('some-random-text/', admin.site.urls),
22. path('', views.home, name='home'),
23. path('count/', views.counter),
24. ]
New path is on line 23. If the comma at the end of line 23 is missing, we would face issues.
This shouldn't be strange. Remember to add a comma to end of every closing bracket. You might also notice that I didn't add a name to the count url and we would get to that shortly.
Now let's go to the home.html file and make one minor addition. We would add the action, which would be the url, which is /count/. And then we head over to count.html and add some strange stuff to the body:
<h3> Vowels Counted - {{ count }}</h3>
This definitely isn't regular html. However, Django allows us to access the contents of the dictionary we returned using this syntax.i.e.
{{ dictionary_key_name }}
Now run your server and check if your code runs.
Mine doesn't π«π©. However, because DEBUG = True in settings.py, we see the error has to do with CRSF verification failed. Well Django requires that for every form, there is a
{% csrf_token %}
CSRF stands for Cross Site Reference Forgery. You should read a little about it.
To prevent againt CSRF, a token is generated on every form submission. So let's go add it:
<form method="POST" action="">
{% csrf_token %}
<textarea name="input-stuff" rows="10" cols="30"></textarea>
<button type="submit">Check vowel count</button>
</form>
Now save, and try again. Ding! Ding!! Ding!!πππππ
Mine works! If yours does, ππ strawberries for you.
One final thing is to test what happens when we change the url from count to counts in the urls.py file.
20. urlpatterns = [
21. path('some-random-text/', admin.site.urls),
22. path('', views.home, name='home'),
23. path('counts/', views.counter),
24. ]
20. urlpatterns = [
21. path('some-random-text/', admin.site.urls),
22. path('', views.home, name='home'),
23. path('count/', views.counter, name='count-vowels'),
24. ]
Now go to home.html and make your opening form tag similar to:
9. <form method="POST" action="{% url 'count-vowels' %}">
Only the action changed to what is known as a template tag. This basically says: search all the urls we have and see if there's any with the name count-vowels. If there is, that is the url we want. And so that works.
As we have seen, the views.py file controls a number of things. This isn't all we can use it for. We would also be talking about models and how we can upload images, maybe a profile picture.
This would be the end of today's article. I know we've been eating fruits, but here π©πΏπ«πͺ, give yourself a tasty treat if you choose to. Cheers.
I almost forgot the carrot, here π₯π₯.
Project can be found here
Cover image by yabayee from Pixabay
Top comments (0)