Views #
Views are the key link between the Model and HTML files. Django has two main types of views:
[1] Class Base Views #
π
Let’s start by looking at our existing class based views in ridde_app/views.py Each view inherits a Django view. For now we are going to ignore NewRiddleForm(FormView). We will go in-depth in forms in a later lab.
IndexView(TemplateView)RiddleListView(ListView)RiddleDetailView(DetailView)
π Take a look at documentation for each Class View
There are a TON of different ways to achieve the same outcome in Django. We will just explore a few of them in this lab.
[TemplateView] #
TemplateView is a view that simply directs the a url path to a HTML file.
π
Let’s look at IndexView(TemplateView). You can view it
HERE.
class IndexView(TemplateView):
template_name = "index.html"
The only attribute
TemplateViewNEEDS is atemplate_name.
βοΈ Let’s add complexity to our IndexView by having a random riddle appear on our index page.
π»
In IndexView(TemplateView) add the get_context_data() function. This is a powerful function that allows you to send data to a template.
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['riddle'] = Riddle.objects.order_by("?").first()
return context
order_by("?")can be slow with larger databases, you can read more about it here if interested
π»
To see the random riddle appear, you will need to use the context['riddle'] in templates/index.html. Add the line below to line 8.
{{riddle}}
π§ You may be wondering, why does it show the question? That is because the __str__() method is overridden in ridde_app/models.py.
def __str__(self):
return f"{self.question}"
π»
Add another Riddle property to the __str() method.
π Refresh http://127.0.0.1:8000/ to see your changes!
π»
Now, return to the index.html page and try just showing the riddle answer, by using the fields.
{{riddle.answer}}
There are multiple ways to have control over what appears in the template!
Context Data is a very powerful dictionary that allows you to send data to your template! You can add as many key, value pairs the context as you need.
context = {
'riddle': Riddle.objects.order_by("?").first()
}
π»
Try, adding a new key,value pair and see if you can access it in index.html
[ListView] #
ListView is a view that sends an entire Queryset of a model. You can think of a Queryset as a list of models.
π
Let’s look at RiddleList(TemplateView).
class RiddleListView(ListView):
model = Riddle
template_name = "riddle_list.html"
queryset = Riddle.objects.all()
- it requires you to specify a
modeland atemplate_name- by defining a
querysetyou can have more control over what data gets sent
π»
Use .order_by() to change the sort order of riddles. Up to you to decide how to sort.
>>> Riddle.objects.order_by('likes')
<QuerySet [<Riddle: Where does today come before yesterday?>, <Riddle: I speak without a mouth and hear without ears. I have no body, but I come alive with wind. What am I?>, <Riddle: who am i?>, <Riddle: What is black when itβs clean and white when itβs dirty?>, <Riddle: Iβm the rare case when today comes before yesterday. What am I?>]>
>>> Riddle.objects.order_by('question')
<QuerySet [<Riddle: I speak without a mouth and hear without ears. I have no body, but I come alive with wind. What am I?>, <Riddle: Iβm the rare case when today comes before yesterday. What am I?>, <Riddle: What is black when itβs clean and white when itβs dirty?>, <Riddle: Where does today come before yesterday?>, <Riddle: who am i?>]>
>>> Riddle.objects.order_by('-question')
<QuerySet [<Riddle: who am i?>, <Riddle: Where does today come before yesterday?>, <Riddle: What is black when itβs clean and white when itβs dirty?>, <Riddle: Iβm the rare case when today comes before yesterday. What am I?>, <Riddle: I speak without a mouth and hear without ears. I have no body, but I come alive with wind. What am I?>]>
- what is the difference between
('question')and('-question')?
π Refresh and visit 127.0.0.1:8000/riddle/list to see your changes!
You can also add the get_context_data() method into a ListView.
π»
Add the get_context_data() method to RiddleList(TemplateView)
- Send data to communicate what how the riddles are sorted
- Display the data on the
riddle_list.htmlpage.
[DetailView] #
DetailView is a view that sends one instance of a model. In this app, it will send one Riddle object.
π
Let’s look at RiddleDetailView(DetailView).
class RiddleDetailView(DetailView):
model = Riddle
template_name = "riddle_detail.html"
- it requires you to specify a
modeland atemplate_name
π
Now, let’s take a look at line 9 in riddle_app/urls.py.
path('riddle/detail/<int:pk>/', RiddleDetailView.as_view(), name='riddle-detail'),
<int:pk>- this tells theDetailViewwhichRiddleto send based on theid
π Try it out by visiting the path
http://127.0.0.1:8000/riddle/detail/1. You can change 1 to any id that is in the database.
You can also add the get_context_data() method into a DetailView.
π»
Add the get_context_data() method to RiddleDetailView(DetailView) to send the current datetime the page is accessed. You will need to reference the resources to figure out how to do this.
- Send data to communicate what time the page was accessed
- Display the data on the
riddle_detail.htmlpage. - Resources
π Test your changes by visiting the path 127.0.0.1:8000/riddle/detail/1.
[2] Function Views #
Function based views are great for when a class based view does not fit your needs or if you want more specific over the GET and POST request cycle. In this app we function based views for:
- liking a riddle
- guessing a riddle
π»
Add a dislike feature to your app that simply the likes. You will need to edit:
riddle_app/models.pyriddle_app/views.pyriddle_app/urls.pyriddle_app/templates/riddle_detail.html
π Test your changes by visiting the path 127.0.0.1:8000/riddle/detail/1.
[3] Deliverables #
β‘β¨
π» Push your work to Github:
git statusgit add -Agit statusgit commit -m "your message goes here"
- be sure to customize this message, do not copy and paste this line
git push
[Extension] #
Try implementing any of these features:
- a new
ListViewto only see easy, medium, or hard riddles - a
UpdateView- to allow a user to change an existingRiddle - a non-destructive way to ‘delete’ riddles by ‘archiving’ them