CS计算机代考程序代写 database Project Environment 3 Django Forms

Project Environment 3 Django Forms

Interacting with our applications
Saw in an earlier class we use forms to allow users to interact with our application and pass data.
We saw a simple example of using an HTML form in a template to allow the user to submit a search query.
To allow users to Create and Update data maintained by our applications, Django provides Django forms.
Django forms provide a simple service: For data input by the user, they provide a place to hold the data temporarily and to validate it.
If all you need is standard validation, Django’s generic views can generate forms automatically given a model class.
COMP3297: Software Engineering 2

As an example, let’s take the Course Management case from earlier.
Remember: Courses have a unique course code, and a name. Some small changes in functionality just for this demo:
The course list will show only course codes, which will link to the details (here, only course name) of their corresponding courses.
COMP3297: Software Engineering 3

Some generic views expect us put a bit of expected “infrastructure” in place first. get_absolute_url()
Generally, hard-coding paths in our code is bad. Every time there is a change, we need to find every occurrence in the code.
We define get_absolute_url() functions that can give us a URL we need from a single authoritative point. And that Django will use, for example, when it wants the URL for an instance.
A common need is for the URL of the “official page” that represents an instance. Usually, this is some form of detail page.
Since the mapping from URL to view of an instance already exists in our URLconfs, we don’t even need to hard code URL details in get_absolute_url(). We can reverse the mapping to obtain the URL.
We’ll see soon this is useful for redirecting the user to the detail of a instance after it has been created or updated successfully.
COMP3297: Software Engineering 4

Reversing a URL pattern
In the Course model:
Also switched to use a UUID field for ID, as an example of this type as primary key
reverse() uses the name we gave to the URL, the number of arguments, and the names of keyword arguments to find the match
COMP3297: Software Engineering
5

Example of use
COMP3297: Software Engineering 6
In the course_list template:
example of overriding content of the base template
Also more useful naming.
This example shows the new context object name explicitly.
That form of the name is such a common choice that Django provides it implicitly. Thus the statement could be omitted and we could still access course_list in our template.

Django’s generic editing views
CRUD operations are a common need. Django provides generic views that work with forms to make CUD very straightforward:
CreateView:
Displays a form for creating an object, and saves the object
UpdateView:
Displays a form for updating an existing object and saves it
DeleteView:
Displays a confirmation page and deletes the object
Those views are all model-based. There is an additional editing view that is not model-based
FormView:
Displays a form and performs corresponding action
COMP3297: Software Engineering 7

Create, with CreateView
In views.py:
Form for course creation (a ModelForm) generated automatically
If success_url is not given a value, Will call get_absolute_url() of new instance for redirect if success_url is not given a value.
Will use a template_name of _form.html by default
8
Remember, our get_absolute_url() reverses this to obtain a URL
In courses/urls.py:
In the course_form.html template:
COMP3297: Software Engineering

In action
Obtained via the model’s COMP3297: Software Engineering get_absolute_url() function9
By template inheritance and overriding
Automatically redirects here on success.

Too much magic?
What is happening with the Form?
Easiest way to understand Django Forms is by their basic purpose and the states they can be in.
The purpose of a Form is to:
create HTML forms for data
hold data temporarily
validate and process the data
pass the result on for further action (such as saving in the database)
Forms contain fields, declared in a similar way to Models. But the fields are different from those of Models.
Form fields are associated with a widget – an HTML element, effectively, so they can be represented to users in the browser.
They don’t know how to represent data in a database – that is the job of Model
fields.
COMP3297: Software Engineering 10

What is happening with the Form?
Ultimately, Django Forms do something with the data. By convention we usually implement a save() method for that purpose (although, it could be send(), etc. instead).
Since we never trust our users and the data in forms comes from users, we can’t trust that it is valid.
So, a big responsibility of a Form is to clean its data. We maintain a clear separation between:
Raw data, that can not be trusted, and
Cleaned data, that has been validated and sanitized.
When implementing save(), for example, we access only the safe cleaned version, never the raw data.
COMP3297: Software Engineering 11

Bound and Valid
There are three possible states a Form can be in:
It either has user data or it doesn’t.
If it has user data, those data are either clean, or they aren’t
A Form that has user data is Bound. The is_bound attribute is True.
The Form’s is_valid() method causes a Form’s data to be validated and cleaned. It returns True only if the data are clean. Clearly, a Form can only be valid if it is bound.
A cleaned_data dictionary is created during validation and cleaning. This contains the safe data we access and use.
An errors dictionary contains the errors detected in data that did not validate successfully.
COMP3297: Software Engineering 12

Customizing validation
We can make is_valid() do whatever we want.
There are two kinds of methods executed during validation:
Validator methods. Clean methods.
Django provides validator methods for its field types. So when we customize, it is by providing custom clean methods.
Example: The Course model class specifies that lists of Course objects should be ordered by Code. Lower-case Codes will mess up the intended ordering.
We can provide a clean method to convert to upper-case any lower-case Codes supplied by the user during Course creation.
COMP3297: Software Engineering 13

Before
COMP3297: Software Engineering 14

Example. Derived from Form
COMP3297: Software Engineering 15
Fields typically mirror those of the corresponding Model class
Custom clean method.
Clean methods for fields are named: clean_()
Typical save() method.
Note, the values used to initialize the instance fields are from the cleaned_data dict
save() methods are expected to return the newly created object.

After
COMP3297: Software Engineering
16

Reducing duplication with ModelForms
Since Forms often closely follow the structure of the Models they serve, it would be convenient if we could connect the Form to the Model.
This is supported by the ModelForm class. Now it is no longer necessary to declare the Form fields, and the save() method is also generated for us.
In fact, this was the class used in the previous example, because
CreateView works with ModelForms, not Forms.
COMP3297: Software Engineering 17

Forms and Templates
There are many ways to render a form as HTML depending on how much control the developer wants over the process.
Recall, each field type has an HTML representation – either the default for the type or a widget specified by the developer.
Generally, for each field in the form, we want to loop over and output: any errors, a label, and the field’s value. We can iterate over the fields in a form and do that as follows:
COMP3297: Software Engineering 18
{% for field in form %} {{ field.errors }}

{{ field.label_tag }} {{ field }}

Forms and Templates
A common approach is to use one of the following shortcuts at first, and then customize as needed.
Each shortcut displays the fields of a form in the order in which they were defined in the form class:
Form.as_p()
Render as a series of

tags, with each containing one field
Form.as_ul()
Render as a series of

  • tags, with each containing one field
    Form.as_table()
    Render as a

    The example from earlier
    COMP3297: Software Engineering 19

    What is the csrf_token tag?
    20
    Cross-Site Request Forgery
    Roughly, this is a form of attack that is made possible because a web application trusts a user based on, say, a cookie saved in the user’s browser following successful authentication.
    Such cookies are included in any request from the browser to the application and thus the requests are accepted as genuine by the application.
    The attacker creates a forged request to the application to perform some state-changing action. The attacker embeds the request in a link that the user is tricked into visiting.
    If the user is currently logged in to the targeted web application, then the request will be made with the required session cookies and accepted as coming from the user. The malicious changes will be made.
    Django protects against this form of attack by expecting any request that submits data, such as a POST request, to include a unique token, the csrf_token, that was included by Django on the form. The data will be accepted only if the token is valid.
    COMP3297: Software Engineering

    User requests to Create object
    GET
    Display Form with error notifications
    [Invalid]
    render
    [Valid]
    redirect
    Create new object and save
    Redirect to success page
    Display default unbound Form
    User updates Form and submits
    render
    POST
    POST
    Validate data
    d
    Not Bound Not Valid
    Bound Not Valid
    Bound Valid
    COMP3297: Software Engineering
    21

    Handling the three states with a Function-Based View
    # FORM IS BOUND AND VALID
    # FORM IS NOT BOUND
    # FORM IS BOUND AND NOT VALID
    # (OR NOT BOUND)
    HTTP POST
    bind data to new form
    create and save new object
    display details (invokes get_absolute_url())
    HTTP GET (or other not POST)
    new unbound form
    display unbound form / bound form with errors
    In courses/urls.py …
    path(‘create/’,course_create_view, name=’course_create’),
    COMP3297: Software Engineering 22

    Handling the three states with a Class-Based View derived from the class-based base view: View
    # FORM IS NOT BOUND
    # FORM IS BOUND AND VALID
    # FORM IS BOUND AND NOT VALID
    display unbound form
    COMP3297: Software Engineering
    23
    display details of new course
    display bound form with errors
    In courses/urls.py …
    path(‘create/’, CourseCreateView.as_view(), name=’course_create’),

    And the equivalent Class-Based View derived from CreateView
    Path unchanged from previous slide:
    In courses/urls.py …
    path(‘create/’, CourseCreateView.as_view(), name=’course_create’),
    COMP3297: Software Engineering
    24

    More complete Django architecture
    Request
    Response
    Middleware
    URL Dispatch
    URL Patterns
    HttpRequest object
    Django website
    Template Loader
    HttpResponse object
    Views
    URL Patterns
    App
    Forms
    Models
    Database
    COMP3297: Software Engineering
    25
    Templates