It is the same for data driven-views, we just use Django models to fetch/store data in our view function
Data-Driven Views
Take advantage of Django Models and ORM to:
Store data
Update data
Fetch data
Delete Data
Basically your CRUD operations
CRUD Views/Operations Can Be On
List of objects
Single object
The Read Operation
List Views
Fetch and display a list of items matching a specific criteria
Model.objects.filter, all, values are used to fetch the list of data and set criteria
Criteria can be set in url or changed based on url
Single Object Views
Model.objects.get is used (replace Model with your model)
Must use primary key or key (unique values) to fetch a single object
Key typically set in url and named variable named pk
One object or none is returned and displayed
Listing Blog Posts
Let’s create the view function:
from django.shortcuts import render
from .models import Post
def list_posts(request):
posts = Post.objects.all()
context = {
'post_list': posts,
}
return render(request, "post_list.html", context)
Let’s Link the View to a URL Path
We are now Django experts, so we link the urls.py in our app to the room urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # includes paths from blog/urls.py
]
Defining The Path
Now we can define all our paths in blog/urls.py:
from . import views
# Alternatively:
# from .views import list_posts
from django.urls import path
urlpatterns = [
path('', views.list_posts),
]
Adding The Last Missing Part
Make sure the directory blog/templates is created
Create post_list.html inside it
post_list.html
<!doctype html>
<html lang="en">
<head><title>Post List</title></head>
<body>
<h1>Latest posts:</h1>
<ul>
{% for post in post_list %}
<li>{{ post.title }}, posted on {{ post.created_on }}</li>
{% endfor %}
</ul>
</body>
</html>
The Result
Database Queries
Remember this line from views.list_posts:
posts = Post.objects.all()
Here we are using the Django ORM to fetch all blog posts
Details of Database Queries
posts = Post.objects.all()
posts: is the variable that will store the results (a list)
Post: is the model we are querying, since we want posts
objects: is known as a model manager, it has all the database related functions
all: is our query
Improved Query
Instead of all, let’s use the filter command to fetch published posts only:
posts = Post.objects.filter(status=1)
status: is the field we want to query on, from models.py (see definition of Post model)
Improved Query
posts = Post.objects.filter(status=1)
Notice we use =, not ==, this is very important
status=1: means we want all Posts in which status is equal to 1
Remember, 1 is published, and 0 is unpublished as defined in models.py
Can you change query to list unpublished posts?
Basic Query Syntax
Use the filter method on the objects model manager
Filtering syntax is:
field_name = value
However, this is for exact value matching
What if we want to perform non-exact matching or date searchers?
get must return a single object (not a list) otherwise it will through an Exception
For our Post models, the exception classes are:
Post.DoesNotExist if object was not found
Post.MultipleObjectsReturned if multiple objects return (not unique)
Typically use for primary key lookup
Updating Blog to Show Post Details
Let’s create the view for displaying a Post:
def show_post(request, id):
post = Post.objects.get(slug=id)
context = {
'post': post,
}
return render(request, "post_detail.html", context)
We will get the id from the URL path, so we include it as a view function argument.
Can you use get_object_or_404 instead?
Shortcut for Using Get
Django provides the shortcut function get_object_or_404 that doesn’t through an error, but displays the 404 page instead
404 error means the page is not found
Most common use case
from django.shortcuts import get_object_or_404
from .models import Post
def show_post(request, pid):
context = {
post = get_object_or_404(Post, pk=pid)
}