Lecture 33

Redirects and forms

MCS 275 Spring 2024
Emily Dumas

View as:   Presentation   ·   PDF-exportable  ·   Printable

Lecture 33: Redirects and forms

Reminders and announcements:

  • Project 4 is due 11:59pm Central on Fri Apr 26.
  • Mon Apr 8 is the last day to submit email proposal for a non-SQLite project 4 topic.
  • I expect to post Project 3 grades and feedback today

Web app updates

Let's review some offline work I did that is similar to what was shown in Lecture 32.

(Result: The task list view is nearly done.)

Web app todo list

  • ☑ HTML mockup
  • ☑ Stylesheet
  • ☑ Learn a bit about Flask
  • ☑ Database schema & test data
  • ☑ Code/template to generate task list
  • ☑ "Wait" button modifies DB
  • ☐ "Wait" button doesn't crash server
  • ☐ Activate rest of buttons
  • ☐ Add page to create new task
  • ☐ Create a front page

Action URLs

  • /task/3/update?status=1 - Change status
  • /task/3/update?shared=0 - Change privacy / sharing flag
  • /task/3/delete - Delete a task (add this later?)

HTTP response code

Every HTTP request results in a numerical status.

So far, we've seen:

  • 404 NOT FOUND
  • 200 OK
  • 500 INTERNAL SERVER ERROR

Redirect

There are also codes that instruct the browser to load another resource, e.g.

  • 301 MOVED PERMANENTLY
    • Means: Moved, make note of it. Never come here again.
  • 302 FOUND
    • Means: Temporary move. This time, you need to check some other place.

return flask.redirect("http://destination/",code=302) will accomplish a redirect.

Web app todo list

  • ☑ HTML mockup
  • ☑ Stylesheet
  • ☑ Learn a bit about Flask
  • ☑ Database schema & test data
  • ☑ Code/template to generate task list
  • ☑ "Wait" button modifies DB
  • ☑ "Wait" button doesn't crash server
  • ☐ Activate rest of buttons
  • ☐ Add page to create new task
  • ☐ Create a front page

Other buttons

We need to slightly upgrade update() so it checks the query parameters and forms a DB query that does whatever is asked.

We'll write one that supports updating multiple columns (even though the buttons don't do that).

Web app todo list

  • ☑ HTML mockup
  • ☑ Stylesheet
  • ☑ Learn a bit about Flask
  • ☑ Database schema & test data
  • ☑ Code/template to generate task list
  • ☑ "Wait" button modifies DB
  • ☑ "Wait" button doesn't crash server
  • ☑ Activate rest of buttons
  • ☐ Add page to create new task
  • ☐ Create a front page

Forms

Interactive elements in an HTML document (text entry, checkbox, dropdown list, etc.)


        

jsfiddle is a nice way to test out form designs (for code that can be public).

Inputs name vs id

Each form input should have both a name and id attribute. Usually they are equal, but they have separate roles:

  • name is what this value is called when submitted to the server.
  • id is used to match an input with its <label>.

Textarea

<input type="text"> is typically for single-line answers.

Longer text entry (multi-line) should be handled with a <textarea> tag.

HTTP request types

GET - load a resource, the only action we've considered so far.

GET requests are supposed to be idempotent, meaning repeating the same request multiple times has the same effect as doing it once.

HTTP request types

POST - submit data and/or request an action.

POST requests are not expected to be idempotent. Browsers typically prevent reloading a POST request, for example.

By default, forms use a GET request and put form data in the URL.

This is usually a bad idea, and a POST request is more appropriate.

Easy change: Add method="post" attribute to the <form> tag.

What form get request looks like

Form values become query parameters, e.g.


        https://example.com/formsub/?full=David%20Dumas&nick=deedee
    

Many ascii characters appear verbatim but others* become % escape sequences with two hex digits. Flask decodes these and makes the parameters available as flask.request.values.get(name).

* The precise encoding scheme is specified in RFC3986. Python's built-in urllib.parse module has functions that perform this type of encoding/decoding: urllib.parse.quote and urllib.parse.unquote. But when using Flask, you never need these!

Form values are made available to the function handling submission through flask.request.values.get(name).

Note that a Flask route must explicitly declare that it accepts POST requests:


        from flask import Flask, request

        # ... app setup ...

        @app.route('/registernick',methods = ['POST', 'GET'])
        def record_fullname_and_nickname():
            print("Received nickname {}".format(
                request.values.get("nick")
            ))
    

Flask functions

All are in the flask module:

  • redirect(url) - Returning this object from a route will cause the HTTP server to issue a 302 response code, telling client to load url instead.
  • abort(http_error_code) - Immediately stop and return a HTTP error code (usually 400 bad request, 401 not authorized, 403 forbidden, or 404 not found).

Routes

  • /tasks/<username>/ - (GET) Task list
  • /task/new/ - (GET) Form to make new task
  • /task/new/submit - (POST) Form target
  • /task/<int:taskid>/update - (GET*) Change task attributes

* These should really be POST but we would need to use javascript or a different button markup to do it because <a> tags generate a GET request.

References

Revision history

  • 2023-04-10 Finalization of the 2023 lecture this was based on
  • 2024-04-01 Initial publication