Code 401 Class 28 Reading Notes
Django Forms
HTML Form: A group of one or more fields/widgets on a web page, which can be used to collect information from users for submission to a server.
action
: The resource/URL where data is to be sent for processing when the form is submitted. If this is not set(or set to an empty string), then the form will be submitted back to the current page URL.method
: The HTTP method used to send the data: post or getPOST
, method should always be used if the data is going to result in a change to the server’s database, because it can be made more resistant to cross-site forgery request attacks.GET
, method should only be used for forms that don’t change user data (for example, a search form). It ios recommended for when you want to be able to bookmark or share the URL.
Declaring a Form
Declaration syntax for a Form
is very similar to that for declaring a Model
, and shares the same field types (and some similar parameters). This makes sens because in both cases we need to ensure that each field handles the right types of data, is constrained to valid data, and has a description for display/documentation.
URL configuration
urlpatterns += [
path('book/<uuid:pk>/renew/', views.renew_book_librarian, name='renew-book-librarian'),
]
View
The view has to render the default form whe it is first called and then either re-render it with error messages if the data is invalid, or process the data and redirect to a new page if the data is valid.
import datetime
from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
from catalog.forms import RenewBookForm
@login_required
@permission_required('catalog.can_mark_returned', raise_exception=True)
def renew_book_librarian(request, pk):
"""View function for renewing a specific BookInstance by librarian."""
book_instance = get_object_or_404(BookInstance, pk=pk)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = RenewBookForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
book_instance.due_back = form.cleaned_data['renewal_date']
book_instance.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-borrowed') )
# If this is a GET (or any other method) create the default form.
else:
proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
context = {
'form': form,
'book_instance': book_instance,
}
return render(request, 'catalog/book_renew_librarian.html', context)
Testing the page
Test to add a link to the renew page next to each item using the template code below. (When testing login, we will need to have the permission “catalog.can_mark_returned” in order to access the renew book page (perhaps use your superuser account)