This article is participating in Python Theme Month. See the link for details

On wechat, Rest cannot be enjoyed by lazy people

preface

Previously, when submitting data to the backend of an HTML page using a form form, you wrote tags that took user input and wrapped them with form tags. In many scenarios, you need to verify user input, such as the length and format of the input. If the input is incorrect, you need to display the corresponding error information in the corresponding position on the page. The Django Form component does just that.

Form component function

To sum up, the main functions of a Django From component are as follows:

(1) Generate HTML tags available for the page;

② Verify the data submitted by users;

③ Keep the last input.

The Form component is basically used

The form component is used in much the same way as the Django model. Now the application defines the form class in views.py as follows:

# views.py
from django import forms
class MyForm(forms.Form) :
    "" # username string type min. 3 digits Max. 8 digits # password string type min. 3 digits Max. 8 digits # Email field must conform to mailbox format [email protected] # label property used to specify field display information" "
    # username The value is a string of 3 to 8 characters
    username = forms.CharField(max_length=8,min_length=3, lable='Username')
    # password, a string of 3 to 8 characters
    password = forms.CharField(max_length=8,min_length=3The lable ='password')
    The email field must conform to the email format
    email = forms.EmailField(lable='email')
Copy the code

There are also two ways to test the environment of the Form component. One way is also through test.py, and the other way is through pyCharm’s Python Console test environment.

# 1 Import the file to be tested
from first import views

# 2 Organize the data to be validated into a dictionary and pass it to the custom form class for validation
form_obj = views.MyForm({'username':'python'.'password':'1026'.'emali':'123'})

Note that this method returns True only if all data is valid
form_obj.is_valid()  # False

# 4 View all the data that passes the verification
form_obj.cleaned_data  # {'username': 'python', 'password': '123'}

# 5 Check all fields that do not conform to the verification rules and the reasons for the inconsistencies. The reasons for the inconsistencies are listed, as there may be multiple reasons for the inconsistencies
form_obj.errors  # {'email': ['Enter a valid email address.']}

If the validation data contains a field that does not exist in the class, the Forms component only validates the field that does not exist
form_obj = views.MyForm({'username':'python'.'password':'1026'.'emali':'[email protected]'.'hobby':'read'})
form_obj.is_valid()  # True

# 7 By default, all fields in a class must pass values, which means that when validating data, by default, more data can be passed, but not less
form_obj = views.MyForm({'username':'jason'.'password':'123'})
form_obj.is_valid()  # False
Copy the code

The validation rule for the Form component summarizes the following methods:

Instantiate an object by passing a value to MyForm: organize the checked fields and data into a dictionary form is_VALID () This method will return only if all the data is validTrueCleaned_data Checks all data that passes the check errors checks all data that does not comply with the check rules and the reasons for the errors, {key: [' '} has_error() checks whether a field is invalidTrueVerification data verifies only the fields in the class. Multiple fields are ignored. By default, all fields in the class must be transmittedCopy the code

The Form component renders the label

The form component automatically renders the input select radio checkbox, but does not automatically render the submit button. The first is the code on the back end, which writes the view function in views.py:

# views.py
def index(request) :
    Create an empty object
    form_obj = MyForm()
    
    if request.method == 'POST':
        If it is too tedious to retrieve user data one by one, and the data needs to be verified in dictionary format, the data obtained by Request. POST is querySet -- dict
        form_obj = MyForm(request.POST)
        If the data is valid, you should operate the database
        if form_obj.is_valid():
            return HttpResponse('OK')
        
    If a GET request is returned, an empty object is passed directly to the HTML page
    return render(request,'register.html'.locals())

Copy the code

If the data is illegal and you need to display error information to the front end, how do you display error information to the front end? Since the form validation generates error messages in dictionary format and custom objects in front end, you can use the front end dot method. Here is the front end register.html page.

<body>
<form action="" method="post" novalidate>  <! -- the novalidate parameter prevents automatic browser validation -->
    {% for form in form_obj %}
        <p>
            {{ form.label }} : {{ form }}
        <! -- SPAN is a reserved label for displaying error messages. Form.errors. 0 means only displaying the first error message, otherwise the Forms component will display the error message as an unordered list.
        <span style="color: red">{{ form.errors.0 }}</span>
        </p>

    {% endfor %}
    <input type="submit">
</form>
</form>
</body>
Copy the code

The error information displayed in the front end is in English, can it be changed to Chinese? You can customize error messages with the error_messages parameter.

class MyForm(forms.Form) :
    The error_messages argument is the data structure that needs to be constructed into a dictionary, with the key being the checksum condition and the value being the message if the checksum fails.
    username = forms.CharField(min_length=5,
                               max_length=12,
                               label='Username',
                               error_messages={
                                   'min_length': 'User name cannot be less than 5 characters'.'max_length': 'User name cannot be more than 12 characters long'.'required': 'User name cannot be empty',
                               }
                               )
    password = forms.CharField(min_length=6, max_length=12, label='password')
    re_password = forms.CharField(min_length=6, max_length=12, label='Confirm password')
    email = forms.EmailField(label='email')
Copy the code

HOOK function

The form components of basic use is only the first layer of the data check, a lot of times for parameters also need some special check rules, then you can use the hooks, hooks is similar to the second check is in the form components, can let us custom validation rules, and after the calibration process through the first layer will come to hook function, You can further customize the validation rules in hook functions, which are local and global. Hook functions are defined in the Form class.

Local hooks

You can use local hooks when you need to add validation rules to individual fields. Such as specifying that a user name cannot contain a hook.

# views.py
class MyForm(forms.Form) :
    username = forms.CharField(min_length=5,
                               max_length=12,
                               label='Username',
                               error_messages={
                                   'min_length':'User name cannot be less than 5 characters'.'max_length':'User name cannot be more than 12 characters long'.'required':'User name cannot be empty',})def clean_username(self) :
        username = self.cleaned_data.get('username')
        if '666' in username:
            self.add_error('username'.'contains the hook')
        return username
Copy the code

Defining local hook functions can be summarized as follows:

① The local hook function name is clean_ field (), and the field is the field of the custom check rule;

(2) In this method, the data of the field is retrieved from cleaned_data, and only the data of the current field can be retrieved from the local hook.

③ If data verification fails, run the add_error method to add error information to the field.

④ The field data taken out by the local hook must be returned.

Global hooks

You can use global hooks when you need to add validation rules to multiple fields. For example, check whether the passwords entered twice are the same:

# views.py
class MyForm(forms.Form) :
    
    password = forms.CharField(min_length=6, max_length=12, label='password')
    re_password = forms.CharField(min_length=6, max_length=12, label='Confirm password')
   
    def clean(self) :
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        ifpassword ! = re_password: self.add_error('re_password'.'Two different passwords entered')

        return self.cleaned_data
Copy the code

Defining global hook functions can be summarized as follows:

Global hooks can retrieve data from any field in cleaned_data.

Cleaned_data must be returned from the global hook.

Form component parameters

First, the common parameters:

Min_length Minimum number of characters Max_LENGTH Maximum number of characters Label Field name Required Specifies whether the control field is required (default required=)True) error_messages User-defined error messages. The structure of the dictionary initial value.inputThe initial value in the box is valueCopy the code

Tags on HTML pages can modify attributes, so the form component is rendered directly. How to modify the attributes of the tag? This is through the Widget parameter, which allows you to modify the attributes of the tag.

class MyForm(forms.Form) :
    username = forms.CharField(min_length=5,
                               max_length=12,
                               widget=forms.widgets.TextInput(attrs={'class': 'form-control'}))

"" "to summarize: Widget = forms. Widgets. (default is () ((and the input [type = 'text']) widget = forms. Widgets. PasswordInput () password format Widget =forms.widgets.EmailInput() Mailbox format Attrs provides field attributes, either built-in or custom; If there are multiple classes: Spaces, separate them. "" "
Copy the code

In the first validation rule, we also support regular validation by using the validators parameter:

from django import forms
from django.core.validators import RegexValidator

class MyForm(forms.Form) :
 
    phone = forms.CharField(label='Mobile phone Number',
                            validators=[
                                RegexValidator(r'^[0-9]+$'.'Please enter a number'),
                                RegexValidator(r'^159[0-9]+$'.'Numbers must start with 159') ",The first argument is a list of regulartable validators and the second argument is a message indicating that the regulartable validator fails.
Copy the code

The form component renders other tags

The Form component can render not only the input box, but also the Radio Select Checkbox tag:

# radio radio
gender = forms.ChoiceField(
    choices=((1."Male"), (2."Female"), (3."Confidential")),
    label="Gender",
    initial=1,
    widget=forms.widgets.RadioSelect()
)

# the checkbox multi-select
hobby = forms.MultipleChoiceField(
    choices=((1."Basketball"), (2."Football"), (3."Bicolor"),),
    label="Hobby",
    initial=[1.3],
    widget=forms.widgets.CheckboxSelectMultiple()
)


Attrs ={'multiple': 'multiple'
hobby2 = forms.ChoiceField(
    choices=((1."Basketball"), (2."Football"), (3."Bicolor"),),
    label="Hobby",
    initial=3,
    widget=forms.widgets.Select()
)

# Pull down multiple selections
hobby3 = forms.MultipleChoiceField(
    choices=((1."Basketball"), (2."Football"), (3."Bicolor"),),
    label="Love 2",
    initial=[1.3],
    widget=forms.widgets.SelectMultiple()
)

Initial = False; initial = True;
keep = forms.ChoiceField(
    choices=(('False'.0), ('True'.1)),
    label="Do you remember your password?",
    initial=' ',
    widget=forms.widgets.CheckboxInput()
)
Copy the code

Additional Settings are required if choices displays data dynamically retrieved from the database when using the choice parameter:

class BookAddForm(forms.Form) :
    name = forms.CharField(label='Book Name',
                           error_messages={'required': 'Book name cannot be empty'},
                           widget=forms.widgets.TextInput())
    
    price = forms.DecimalField(label='price',
                               error_messages={'required': 'Book prices cannot be empty'},
                               widget=forms.widgets.TextInput())
    
    publish_date = forms.DateField(label='Date of Publication',
                                   error_messages={'required': 'Publication date cannot be empty'},
                                   widget=forms.widgets.DateInput())
    
    publish_id = forms.ChoiceField(label='Publishing house',
                                   error_messages={'required':'Publishing house cannot be empty'},
                                   widget=forms.widgets.Select())
    
    author = forms.MultipleChoiceField(label='the writer',
                                       error_messages={'required':'Author cannot be empty'},
                                       widget=forms.widgets.SelectMultiple())

    def __init__(self, *args, **kwargs) :
        super().__init__(*args, **kwargs)
        The # choices field is dynamically sourced from the database
        self.fields['publish_id'].choices = models.Publish.objects.values_list('pk'.'name')
        self.fields['author'].choices = models.Author.objects.values_list('pk'.'name')
Copy the code

conclusion

The article was first published in the wechat public account Program Yuan Xiaozhuang, at the same time in nuggets.

The code word is not easy, reprint please explain the source, pass by the little friends of the lovely little finger point like and then go (╹▽╹)