Django Learning-Lecture 13 (Part 2): Forms (1) forms.form, forms.modelform

1. The difference between html form and django form

Form in HTML:

Purely from the front-end html, the form is used to submit data to the server, regardless of whether the back-end server uses Django, PHP or other languages. Just put the input tag in the form tag, and then add a submit button, then click the submit button later, you can submit the corresponding value in the input tag to the server.

Forms in Django

The forms in Django enrich the forms in the traditional HTML language. Forms in Django mainly do the following two things

    1. Render the form template.
    1. The form verification data is legal.

2. The process of using forms in Django

Before explaining the details of each part of the Django form. Let's first look at the overall usage process.
First we define a form class in the backend server, inherited fromdjango.forms.Form

# forms.py
class MessageBoardForm(forms.Form):
    title = forms.CharField(max_length=3,label='标题',min_length=2,error_messages={"min_length":'标题字符段不符合要求!'})
    content = forms.CharField(widget=forms.Textarea,label='内容',error_messages={"required":'content字段必须填写!'})
    email = forms.EmailField(label='邮箱')
    reply = forms.BooleanField(required=False,label='回复')

Then in the view, do the corresponding operation according to whether it is a GET or POST request. If it is a GET request, then an empty form is returned. If it is a POST request, the submitted data will be verified.

from .forms import MessageForm
from django.views import View
from django.forms.utils import ErrorDict

class IndexView(View):
    def get(self,request):
        form = MessageBoardForm()
        return render(request,'index.html',{'form':form})
    
    def post(self,request):
        form = MessageBoardForm(request.POST)
        if form.is_valid():
            title = form.cleaned_data.get('title')
            content = form.cleaned_data.get('content')
            email = form.cleaned_data.get('email')
            reply = form.cleaned_data.get('reply')
            return HttpResponse('success')
        else:
            print(form.errors)
            return HttpResponse('fail')

When using a GET request, we pass a form to the template, and then the template can use the form to generate the html code of a form. When using a POST request, we build a new form based on the data uploaded from the front end. This form is used to verify whether the data is legal. If the data is verified, then we can get the corresponding data through cleaned_data. Render the HTML of the form in the template

<form action="" method="post">
    <table>
        {
   
   { form.as_table }}
        <tr>
            <td></td>
            <td><input type="submit" value="提交"></td>
        </tr>
    </table>
</form>

We gave a form tag on the outside, and then used the table tag to beautify it. When using the form object to render, we use the table method. Of course, you can also use the ul method (as_ul) or use it. The way of p tag (as_p), and we also added a submit button at the back. This will generate a form

2.1. Fields commonly used in django forms

Using Field can be the first step in data validation. What type of data do you expect the submitted data to be, then what type of Field is used.

CharField

Used to receive text.

参数:
max_length:这个字段值的最大长度。
min_length:这个字段值的最小长度。
required:这个字段是否是必须的。默认是必须的。
error_messages:在某个条件验证失败的时候,给出错误信息。

EmailField

用来接收邮件,会自动验证邮件是否合法。
错误信息的key:required、invalid。

FloatField

Used to receive the floating point type, and if the verification is passed, the value of this field will be converted to the floating point type.

参数:
max_value:最大的值。
min_value:最小的值。
错误信息的key:required、invalid、max_value、min_value。

IntegerField

Used to receive shaping, and after verification is passed, the value of this field will be converted to shaping.

参数:
max_value:最大的值。
min_value:最小的值。
错误信息的key:required、invalid、max_value、min_value。

URLField

用来接收url格式的字符串。
错误信息的key:required、invalid。

2.2 Common validators for django forms

When validating a field, you can pass a validators parameter to specify the validator to further filter the data. There are many validators, but we can actually specify many validators through this Field or some parameters. For example EmailValidator, we can EmailFieldspecify by, for example MaxValueValidator, we can max_valuespecify by parameters.
##### Here are some commonly used validators:
MaxValueValidator:Verify the maximum value.
MinValueValidator: Verify the minimum value.
MinLengthValidator: Verify the minimum length.
MaxLengthValidator: Verify the maximum length.
EmailValidator: Verify whether it is the mailbox format.
URLValidator: Verify whether it is in URL format.
RegexValidator: If you need more complex validation, then we can use the regular expression validator: RegexValidator. For example, if we want to verify whether the mobile phone number is qualified, we can use the following code to achieve:

class MyForm(forms.Form):
    telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])

2.3. django form custom validation

Sometimes the validation of a field is not a length. A regular expression can be written clearly, and some other complex logic is needed. Then we can perform custom validation on a field. For example, in the registration form verification, we want to verify whether the mobile phone number has been registered, then we need to judge it in the database at this time. Verify way to customize a field is to define a method, the name of this method is to define rules: clean_fieldname. If the verification fails, then a verification error is thrown. For example, to verify whether the mobile phone number in the user table exists in the database before, you can use the following code to achieve:

class MyForm(forms.Form):
    telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])

    def clean_telephone(self):
        telephone = self.cleaned_data.get('telephone')
        exists = User.objects.filter(telephone=telephone).exists()
        if exists:
            raise forms.ValidationError("手机号码已经存在!")
        return telephone

The above is to verify a field. If you need to verify multiple fields when verifying data, you can override the clean method. For example, when registering, it is necessary to judge whether the two passwords submitted are equal. Then you can use the following code to complete:

class MyForm(forms.Form):
    telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])
    pwd1 = forms.CharField(max_length=12)
    pwd2 = forms.CharField(max_length=12)

    def clean(self):
        cleaned_data = super().clean()
        pwd1 = cleaned_data.get('pwd1')
        pwd2 = cleaned_data.get('pwd2')
        if pwd1 != pwd2:
            raise forms.ValidationError('两个密码不一致!')

2.4. Django form extraction error information

If the verification fails, then there are some error messages that we need to pass to the front end. At this time, we can get it through the following attributes:
1 form.errors.: The error message obtained by this attribute is an error message that contains html tags.

2 form.errors.get_json_data().: What this method gets is a dictionary type error message. A dictionary with the name of a field as the key and the error message as the value.

3 form.as_json().: This method is to dump the dictionary returned by form.get_json_data() into a json format string for easy transmission.

4. The error value of the field obtained by the above method is a relatively complex data. For example, the following:

{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensure this value has at most 4 characters (it has 22).', 'code': 'max_length'}]}

So if I just want to put the error information in a list, not in a dictionary. At this time, we can define a method to rearrange this data.

class MyForm(forms.Form):
    username = forms.URLField(max_length=4)

    def get_errors(self):
        errors = self.errors.get_json_data()
        new_errors = {}
        for key,message_dicts in errors.items():
            messages = []
            for message in message_dicts:
                messages.append(message['message'])
            new_errors[key] = messages
        return new_errors

In this way, all error messages of a certain field can be directly placed in this list.

3. Modelform of django form

When you write a form, you will find that the Field in the form is basically the same as the Field in the model, and the data that needs to be verified in the form is what needs to be saved in our model. Then we can bind the fields in the model with the fields in the form at this time.

For example, there is an Article model.

from django.db import models
from django.core import validators
class Article(models.Model):
    title = models.CharField(max_length=10,validators=[validators.MinLengthValidator(limit_value=3)])
    content = models.TextField()
    author = models.CharField(max_length=100)
    category = models.CharField(max_length=100)
    create_time = models.DateTimeField(auto_now_add=True)

Then when writing the form, there is no need to repeat all the fields in the Article model one by one.

from django import forms
class MyForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = "__all__"

MyFormIt is inherited from forms.ModelForm, and then a Metaclass is defined in the form, model=Article is specified in the Meta class, and fields="**all**"all the fields in the Article model can be copied for verification. If you only want to verify a few of the fields, you can specify a list for fields and write the required fields. For example, if you only want to verify title and content, you can use the following code to achieve

from django import forms
class MyForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title','content']

If there are more fields to be verified, except for a few fields that do not need to be verified, you can use excludethem instead fields. For example, I don’t want to verify category, so the sample code is as follows:

class MyForm(forms.ModelForm):
    class Meta:
        model = Article
        exclude = ['category']

3.1 Custom error message

Use ModelForm, because the fields are not defined in the form, but in the model, so some error messages cannot be defined in the field. Then you can Metadefine in the class at this time error_messages, and then write the corresponding error message into it.

class MyForm(forms.ModelForm):
    class Meta:
        model = Article
        exclude = ['category']
        error_messages  ={
            'title':{
                'max_length': '最多不能超过10个字符!',
                'min_length': '最少不能少于3个字符!'
            },
            'content': {
                'required': '必须输入content!',
            }
        }

3.2 save method

ModelFormThere is also a savemethod, you can call the savemethod directly after the verification is completed , you can save the data in the database

form = MyForm(request.POST)
if form.is_valid():
    form.save()
    return HttpResponse('succes')
else:
    print(form.get_errors())
    return HttpResponse('fail')

This method must be used after clean has no problem. If used cleanbefore, an exception will be thrown. In addition, when we call the savemethod, if we pass in a `commit=False, then only the object of this model will be generated, and this object will not be inserted into the database. For example, the field validated on the form does not contain all the fields in the model. At this time, you can create the object first, and then fill in other fields according to the field, and then save the value of all the fields in the database.

form = MyForm(request.POST)
if form.is_valid():
    article = form.save(commit=False)
    article.category = 'Python'
    article.save()
    return HttpResponse('succes')
else:
    print(form.get_errors())
    return HttpResponse('fail')

Guess you like

Origin blog.csdn.net/scyllake/article/details/109263796