Beginner IT: Django framework - form component and model form

Article catalog

1, form introduction

I know that the front-end page can submit data to the back-end through the form table, and I need to wrap the tags that get user input with the form form.

At the same time, in many scenarios, we need to verify the user's input. For example, if the length / format is illegal, we want to prompt the user with the corresponding error information at the corresponding location.

If we use js to achieve the above effects, it must be possible, but the process is very complex. The form component in Django helps us encapsulate all the above functions, which can be achieved only by calling some interfaces.

1. Function of form component

Function of form component

  1. Generate the HTML tag corresponding to the front page through the form component of the back end
  2. Verify the validity of the data submitted by the front-end form page, and give corresponding prompts
  3. After verification, the input content of the front-end page can be retained to increase the user experience

2. Simple use of form component

Database model preparation

New project form_ In the app01 file models.py

models.py

Execute the synchronization instructions make migrations and migrate to synchronize to the database. After adding some data, the table structure is as follows

form easy to use

Before using form, you need to define a class to inherit forms.Form .

In order to keep the project clean, we will create another folder named utils, where we will write the classes we want to define

from django import forms

class LoginForm(forms.Form):
    # Define your own class according to the form component, and you need to inherit forms.Form
    username = forms.CharField(
        label="user name",
        min_length=8,
        error_messages={
            "required": "Cannot be empty",
            "invalid": "Format error",
            "min_length": "Minimum 8 digits of user name"
        },
        widget=forms.widgets.TextInput(attrs={"class": "form-control"})
    )  # The form field name is the name attribute of the front-end input tag.
    password = forms.CharField(
        label="password",
        min_length=12,
        widget=forms.widgets.PasswordInput(attrs={"class": "form-control"})
    )
Write registration function in view function
from django.shortcuts import render,HttpResponse,redirect
from utils.formlesson import LoginForm  # Import custom RegFrom class

def login(request):
    form_obj = LoginForm()  # Instantiate a form object
    if request.method=="POST":
        form_obj = LoginForm(data=request.POST)  # Perform form verification on the same data of the name attribute value of the input tag and the form field
        if form_obj.is_valid() and request.POST.get("username") == "alex" and request.POST.get("password") == "alex":  # Using is_valid method to determine whether the submitted data is legal
            return HttpResponse("Login successful")
    return render(request,"login.html",{"form_obj":form_obj})  # If it is a get request, return to the page, and get the html tag through the form object rendering at the front end.
template file login.html file
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="col-sm-6 col-sm-offset-3">
        <form action="{% url 'register' %}" method="post" novalidate>  <!--novalidate Tell the browser that the input does not need to be verified,So that we can use our own verification tips-->
            {% csrf_token %}
            <!--The first way to write:Directly generated, but not conducive to personalized customization-->
            {{ form_obj.as_p }}


            <!--The second way: more personalized customization-->
            <div class="form-group">
                <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
                <!--obtaininputTaggedidtoforProperties, getting label Name of tip-->
                {{ form_obj.username }}  <!--obtain form Object's fields name,generate name="name"Ofinputlabel-->
                {{ form_obj.username.errors.0 }}  <!--obtain name Error prompt after field verification-->
                {{ form_obj.errors }}  <!--obtain form Label global error prompt,It's got all the statisticsinputError message for label-->
            </div>

            <div class="form-group">
                <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label>
                {{ form_obj.password }}
                {{ form_obj.password.errors.0 }}
            </div>

            <!--The third way: throughforFields in circular objects are easier to write-->
            {% for field in form_obj %}  <!--loop form All fields in object,Generate corresponding labels for each field-->
                <div class="form-group">
                    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                    {{ field }}
                    {{ field.errors.0 }}
                </div>
            {% endfor %}
            <input type="submit">
        </form>
    </div>
    <div class="row">

        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>

Through the front-end page effect, the function of form component is verified

  1. The front-end page is generated by the object of form class -- > generating HTML tag function
  2. When the user name and password are blank or wrong, the page will prompt the user to submit the verification function
  3. When the user enters the last input again after the error, the last input remains in the input box -- > the last input remains

2, Common field constraints and plug-ins in Form

When creating a Form class, it mainly involves fields and plug-ins. Fields are used to verify the data requested by users, and plug-ins are used to generate HTML automatically;

1. Common field constraints and corresponding plug-ins

We define another registration form class in formlesson to demonstrate the label effect of different field constraints.

adopt forms.widgets . plug in name (attrs={key,val}) to specify the plug-in and add attributes for the tag. The added attributes can apply the style class in bootstrap.

initial

Initial is the initial value in the input tag input box

from django import forms  # Import from module
class RegForm(forms.Form):
    username = forms.CharField(
        min_length=8,  # Minimum length of user name
        label="user name",
        initial="Zhang San",
        widget=forms.widgets.TextInput(attrs={"class":"form-control"})
    )

error_messages

Custom error message prompt content

class RegForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="user name",
        initial="Zhang San",
        error_messages={  # Custom error message prompt content
            "required": "Content cannot be empty",  # Originally
            "invalid": "Format error",
            "min_length": "Minimum 8 digits of user name"
        },
        widget=forms.widgets.TextInput(attrs={"class":"form-control"})  # Add a plug-in to the input tag and add the property bootstrap style property
    )

password

The input tag used to get the user's input password,

class RegForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="user name",
        initial="Zhang San",
        error_messages={  # Custom error message prompt content
            "required": "Content cannot be empty",  # Originally
            "invalid": "Format error",
            "min_length": "Minimum 8 digits of user name"
        },
        widget=forms.widgets.TextInput(attrs={"class":"form-control"})  # Add a plug-in to the input tag and add the property bootstrap style property
    )

radioSelect

Generate the input tag to get the radio box selected by the user

class RegForm(forms.Form):
    gender = forms.ChoiceField(
        choices=((1,"male"),(2,"female"),(3,"secrecy")),  # name value and corresponding display text in radio box
        label="Gender",
        initial=3,
        widget=forms.widgets.RadioSelect()  # Radio drop-down selection box plug-in, add style
    )

Radio Select

Generate the select label of the radio drop-down selection box to get user input

class RegForm(forms.Form):
    hobby = forms.ChoiceField(  # Note that the radio box uses ChoiceField, and the plug-in is select. Otherwise, an error will be reported during validation. Select a valid choice is wrong.
        choices=((1, "Basketball"), (2, "Football"), (3, "Dichroic sphere"),),
        label="hobby",
        initial=3,
        widget=forms.widgets.Select(attrs={'class': 'form-control'})
    )

Multiple Select

Generate the select tab of the multi select drop-down selection box to get user input

class RegForm(forms.Form):
    hobby = forms.MultipleChoiceField(  # Note that MultipleChoiceField and the plug-in is SelectMultiple, otherwise an error will be reported during validation
        choices=((1, "Basketball"), (2, "Football"), (3, "Dichroic sphere"),),
        label="hobby",
        initial=3,
        widget=forms.widgets.SelectMultiple(attrs={'class': 'form-control'})
    )

Radio checkbox

Generate get user's multiple selection box (single choice)

class RegForm(forms.Form):
    keep = forms.ChoiceField(
        choice=(
            ("True",1),
            ("False",0)
        ),
        label="Remember password or not",
        initial="checked",
        widget=forms.widgets.CheckboxInput()  # Radio check box plug-in
    )

Note that in the radio checkbox, the data submitted by form verification is checked to be {"keep", "true"}, and not checked to be {"keep", "false"}. Therefore, you need to give qualified options in choices. choice=((“True”,1),(“False”,1)). Instead of the val property {"keep", "chekced"} set by initial.

Multiple checkbox es

Generate get multiple selection box for users (multiple selection)

class RegForm(forms.Form):
    hobby = forms.MultipleChoiceField(
        choices=((1, "Basketball"), (2, "Football"), (3, "Dichroic sphere"),),
        label="hobby",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()  # Multiple checkbox plug-ins
    )

date type

Generate input tag to get user selected time

class RegForm(forms.Form):
    reg_date = forms.DateField(widget=forms.widgets.TextInput(attrs={'type':'date','class': 'form-control'}))  #type must be specified, otherwise it cannot be rendered as the input box for time selection

The view function register corresponding to the above example

from django.shortcuts import render,HttpResponse,redirect
from utils.formlesson import LoginForm
def register(request):
    form_obj = RegForm()
    if request.method == "POST":
        form_obj = RegForm(data=request.POST)
        if form_obj.is_valid():
            print(form_obj.fields)  # Contains all the fields in the form object, an orderedDict. orderedDict([('username', < django.forms.fields .CharField object at 0x000002138B52C9E8>), ('password', < django.forms.fields .CharField object at 0x000002138B52CA20>)])
            print(form_obj.cleaned_data)  # It contains the verified data, python dictionary type, {'username':'raoyixiong ','password':'ryxiong '}
            return HttpResponse("login was successful")
        else:
            return render(request, "register.html", {"form_obj":form_obj})
    return render(request, "register.html", {"form_obj":form_obj})

2. The choice field obtains the database data

When selecting tags, the options of choices should not be fixed and write dead, and should be able to get real-time updates from the database. However, because the values obtained by static fields cannot be updated in real time, the construction method needs to be rewritten to achieve real-time updates of choices.

Mode 1: implementation of init method

from django import forms
from app01 import models
class BookForm(forms.Form):
    publish_id = forms.fields.ChoiceField(
        # choices=((1, 'ancient poetry Publishing House'), (2, 'foreign famous works Publishing House'),),
        initial=2,
        widget=forms.widgets.Select(attrs={'class': 'form-control'})
    )

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)  # Pay attention to overriding the init method of the parent class. There are many functions implemented in the init method of the parent class
        self.fields["publish_id"].choices=models.Publish.objects.all().values_list("pk","name")
Corresponding view function
from django.shortcuts import render,HttpResponse,redirect
from utils.formlesson import BookForm
def book(request):
    form_obj = BookForm()
    if request.method=="POST":
        print(request.POST)
        form_obj = BookForm(request.POST)
        return render(request,"book.html",{"form_obj":form_obj})
    return render(request,"book.html",{"form_obj":form_obj})

Several points for attention

  1. If the submitted data needs to be written into the database, the field (property) of the data obtained by the form must correspond to the field name written into the table (that is, the same).
  2. The extracted data passes through value_list gets the tuple data of the option. Select the value value of the input tag and the data corresponding to the displayed text. For example, the pk field corresponds to the value value submitted by the input box, and the name field corresponds to the text displayed by the input box to the user.

Method 2: set through the queryset attribute in the field

The selection box is generated by specifying the data object obtained by model model query through the field property queryset in form class.

be careful:

Need to be defined in the model table__ str__ Method, so that a field name in the table can be displayed in the front end, otherwise it will be directly displayed as an object, which is not conducive to reading.

from django import forms
from app01 import models
class BookForm(forms.Form):
    # Single choice Publishing House
    publish_id = forms.ModelChoiceField(
        queryset=models.Publish.objects.all(),
        widget=forms.widgets.Select(attrs={'class': 'form-control'}),
    )

    # Multiple choice of authors
    authors = forms.ModelMultipleChoiceField(
        queryset=models.Author.objects.all(),
        widget=forms.widgets.SelectMultiple(attrs={'class': 'form-control'})
    )

3, All built-in fields in form

1. Built in fields

Field field

  • required=True, whether null is allowed
  • widget=None, HTML plug-in
  • label=None, used to generate label label or display content
  • initial=None, initial
  • help_text = ', help message (displayed next to label)
  • error_messages=None, error message {'required': 'cannot be empty', 'invalid': 'format error'}
  • validators = [], custom validation rules
  • localize=False, do you support localization
  • disabled=False, whether it can be edited
  • label_suffix=None Label content suffix

CharField(Field)

  • max_length=None, maximum length
  • min_length=None, minimum length
  • strip=True remove user input blank

IntegerField(Field)

  • max_value=None, maximum
  • min_value=None, minimum

FloatField(IntegerField) and DecimalField(IntegerField)

  • max_value=None, maximum
  • min_value=None, minimum
  • max_digits=None, total length
  • decimal_places=None, decimal length

BaseTemporalField(Field)

  • input_formats=None time format
  • DateField(BaseTemporalField) format: 2015-09-01
  • TimeField(BaseTemporalField) format: 11:12
  • DateTimeField(BaseTemporalField) format: 2015-09-01 11:12
  • DurationField(Field) interval:% d% H:% m:% s.% F

RegexField(CharField)

  • regex, custom regular expression
  • max_length=None, maximum length
  • min_length=None, minimum length
  • error_message=None, ignored, error message uses error_messages={‘invalid’: ‘…’ }

FileField(Field)

  • allow_empty_file=False allow empty file

Note: the PIL module is required. When using the above two dictionaries, two points need to be noted:

  • enctype = "multipart / form data" in form form
  • Obj = myform in the view function( request.POST , request.FILES )

ChoiceField(Field)

  • Choices = (), options, such as: choices = ((0, 'Shanghai'), (1, 'Beijing'),)
  • required=True, required or not
  • widget=None, plug-in, default select plug-in
  • label=None, Label content
  • initial=None, initial
  • help_text = ', help tips

ModelChoiceField(ChoiceField)

... django.forms.models.ModelChoiceField

  • queryset, query the data in the database
  • empty_label = "---------", default empty display content
  • To_ field_ Name = none, the field corresponding to the value in HTML
  • limit_ choices_ To = none ා secondary filtering of queryset in modelform

ModelMultipleChoiceField(ModelChoiceField)

... django.forms.models.ModelMultipleChoiceField

TypedChoiceField(ChoiceField)

  • coerce = lambda val: val convert the selected value once
  • empty_value = default value of 'null value

TypedMultipleChoiceField(MultipleChoiceField)

  • coerce = lambda val: val convert every selected value
  • empty_value = default value of 'null value

ComboField(Field)

  • fields = () use multiple validations, as follows: verify the maximum length of 20 and the mailbox format
  • fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])

MultiValueField(Field)

PS: abstract class. It can aggregate multiple dictionaries to match a value in a subclass. It should be used with MultiWidget

SplitDateTimeField(MultiValueField)

  • input_date_formats=None, format list: ['% Y –% m –% d', 'm%d/%Y', 'm/%d/%y']
  • input_time_formats=None format list: ['% H:%M:%S',' H:%M:%S.%f ',' H:%M ']
  • FilePathField(ChoiceField) file option. The files in the directory are displayed in the page
  • Path, folder path
  • match=None, regular match
  • recursive=False, recurse the following folder
  • allow_files=True, allow files
  • allow_folders=False, allow folders
  • required=True,
  • widget=None,
  • label=None,
  • initial=None,
  • help_text=''

GenericIPAddressField

  • protocol = 'both', the IP formats supported by both, IPv4 and IPv6
  • unpack_ipv4=False resolves the ipv4 address, if it is: ffff:192.0.2.1 It can be resolved to 192.0.2.1, and PS: protocol must be both to be enabled

SlugField(CharField) number, letter, underscore, minus (hyphen)

4, Field verification

1.RegexValidator

The field in the custom class has a property validators to specify validation rules

Syntax:

validators = [RegexValidator('regular expression ', 'Content of format error prompt')],

Use case

from django import forms
from django.core.validators import RegexValidator
class RegForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="user name",
        widget=forms.widgets.TextInput(attrs={"class": "form-control"}),
    validators = [RegexValidator(r'^[0-9]+$', 'please enter a number'), RegexValidator(r'^159[0-9]+$', 'Number must start with 159')],
    ) 

2. User defined validation function

stay formlesson.py Define your own validation function in. Note that it is a function, not a class method.

import re
from django import forms
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

def mobile_validate(value):  # value is the returned clean after verification_ Data data
  mobile_re = re.compile(r"^13[0-9]|15[012356789][0-9]{8}$")
  if not mobile_re.match(value):  # No match, return None, throw an exception
      raise ValidationError("Incorrect format of mobile number")  # Throw an exception if the verification fails

Try to use custom validation function in register class

class RegForm(forms.Form):
    telephone = forms.CharField(
        max_length=11,
        min_length=11,
        widget=forms.widgets.TextInput(attrs={'class': "form-control",'placeholder': '11 Digit phone number'}),
        validators=[mobile_validate, ]  # Use the custom function to verify the phone number.
    )

5, Hook usage

In addition to the above two ways, you can also define the hook function in From to implement the custom verification function.

1. Define local hook

Define clean in the Fom class_ The field name () method can verify specific fields.

usage method

class LoginForm(forms.Form):
    # Define your own class according to the form component, and you need to inherit forms.Form
    username = forms.CharField(
        label="user name",
        min_length=8,
        error_messages={
            "required": "Cannot be empty",
            "invalid": "Format error",
            "min_length": "Minimum 8 digits of user name"
        },
        widget=forms.widgets.TextInput(attrs={"class": "form-control"})
    )  # The form field name is the name attribute of the front-end input tag.
    
    # A custom local hook is used to verify the username field. It can be verified after the previous verification
    def clean_username(self):
        value = self.cleaned_data.get("username")  # Because the custom hook is only verified after the form verification and the custom verification function are executed, so clean_ There must be data in data.
        if "666" in value:
            raise ValidationError("666 can't log in")
        else:
            return value  # Instant compliance also requires cleaning_ Data returned

2. Define global hook

We define the clean() method in the Fom class, which can realize the global verification of the field.

When all fields are verified and all local hooks are executed, the global hook verification is executed.

usage method

class LoginForm(forms.Form):
    # Define your own class according to the form component, and you need to inherit forms.Form
    username = forms.CharField(
        label="user name",
        min_length=8,
        error_messages={
            "required": "Cannot be empty",
            "invalid": "Format error",
            "min_length": "Minimum 8 digits of user name"
        },
        widget=forms.widgets.TextInput(attrs={"class": "form-control"})
    )  # The form field name is the name attribute of the front-end input tag.
    
    # Enter password for the first time
    password = forms.CharField(
        label="password",
        min_length=12,
        widget=forms.widgets.PasswordInput(attrs={"class": "form-control"})
    )
    
    # Confirm password
    re_password = forms.CharField(
        label="Confirm password",
        min_length=12,
        widget=forms.widgets.PasswordInput(attrs={"class": "form-control"})
    )
    
    # Define global verification hook
    def clean(self):
        pwd1 = self.cleaned_data.get("password")
        pwd2 = self.cleaned_data.get("re_password")
        if pwd1 == pwd2:
            return self.cleaned_data  # Return all cleaned_data (qualified data)
        else:
            # raise ValidationError('the two passwords are not the same! ')
            # Note that in the global hook, the error prompt of exception report is directly thrown. By default, it is in the global error variable, i.e self.errors in

            self.add_error('re_password',"The two passwords are inconsistent!")
            # If you need to specify prompt after a label, you need to add this error to the corresponding label error attribute.
            print(self.re_password.errors)  

Note:

  1. In the global hook, the error prompt of exception report is directly thrown. By default, it is in the global error variable self.fields.errors Medium.
  2. If you need to specify a prompt after a label, you need to add this error to the corresponding label error property self.errors Medium.

6, ModelForm use

1. What is ModelFrom

Usually in Django projects, most of the forms we write are closely mapped to Django's model.

If we want to add and edit book information to this model through the form component, in this case, it is redundant to redefine all fields in the model in the form component.

For this reason, Django provides a helper class that allows us to create Form components through Django's model model model. This class is ModelForm.

Model form is the combination of form and model. It will be automatically converted into form field according to some fields in your model. It can also generate label according to form.

Simple use of ModelForm

For example, we define a data model class Book in the models file

from django.db import models
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)
    publish=models.ForeignKey(to="Publish",to_field="nid")
    authors=models.ManyToManyField(to='Author',)
    def __str__(self):
        return self.title

Using ModelFrom also needs to define a file in which to write the corresponding class.

Here, we define a utils file under the project path, like the form component, and create a modelFromLesson file in which our classes are defined.

class BookModelForm(forms.ModelForm):
    class Meta:
        model = models.Book  # Specify to validate a table
        fields = "__all__"  # Wei all__ Represents all fields. The list specifies some fields
        # exclude = ["title"]  # Specify to exclude some fields
        labels = {  # Specifies the display text for the label label
            "title":"title",
            "price":"Price"
        }
        error_messages = {  # Specifies the error information when the field validation error occurs. You can write any field
            "title": {"required":"Content cannot be empty",}
        }
        widgets = {  # Specify the plug-in type for the field
            "title": forms.widgets.TextInput(attrs={"class": "form-control"}),
            "publishDate": forms.widgets.DateInput(attrs={"class": "form-control"}),
        }

    # Using init method to batch add bootstrap style to labels of all fields
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        for field in self.fields:
            self.fields[field].widget.attrs.update({
                "class":"form-control"
            })

    # Define local hook
    def clean_title(self):
        val = self.cleaned_data.get("title")
        # Here is your custom verification rule
        return val

    # Define global hook
    def clean(self):
        val = self.cleaned_data
        # Write your custom inspection rules
        return val

2.class Meta parameter

Use class Meta in BookForm to specify the detailed settings for the fields in the table.

  • Model property: specifies which class in the model, that is, the table
  • fields: "__ all__ "Indicates that form authenticates all dictionaries, and lists can be used to specify certain fields.
  • Exclude: use the list to specify some fields to exclude.
  • Labels: display text used to specify label labels
  • help_texts: used to specify help text prompt content
  • widgets: Specifies the plug-in type of the field
  • error_messages: specify error prompts for different fields by key value pairs
# Define error messages
error_messages = {
    'title':{'required':'Cannot be empty',...} #All errors of each field can be written
}

Define local and global hooks

It is used the same way as the form component class.

  • Defining clean in a class_ The method of field name is local hook
  • The way to define clean in a class is a global hook
from django import forms
class BookModelForm(forms.ModelForm):  # Create a modelform class
    # Define local hook
    def clean_title(self):
        pass
    # Define global hook
    def clean(self):
        pass

Bulk add style

Batch add style is the same as form, overriding init method in class

from django import forms
class BookModelForm(forms.ModelForm):  # Create a modelform class
    def __init__(self, *args, **kwargs):  # Batch operation
        super().__init__(*args, **kwargs)
        for field in self.fields:
            # field.error_messages = {'required':'Cannot be empty'} #Batch add error information. It's the same error. If it's different, write it separately.
            self.fields[field].widget.attrs.update({'class': 'form-control'})

3. Validation of modelform

The validation of ModelForm is similar to that of Form, which is verified by calling is_valid() or implicitly when accessing the errors property. You can also customize local hooks and global hooks to implement custom verification rules.

If we do not override the specific fields and set the validators property, the model form is verified according to the validators of the fields in the model.

from django.shortcuts import render, redirect, HttpResponse
from utils.modelFormLesson import BookModelForm
from app01 import models
def create_book(request):
    if request.method == "GET":
        book_obj = BookModelForm()  # Generate a book object from ModelForm
        return render(request, "create_book.html", {"book_obj": book_obj})  # The book object is passed to the front end for rendering
    else:
        data = request.POST
        book_obj = BookModelForm(data)  # Verify based on user data
        if book_obj.is_valid():  # Verify whether the data submitted by the user is consistent with the
            book_obj.save()  # Save the data to the corresponding table, because we have specified the table in Meta, so it can be recognized automatically. This sentence essentially completes the following three things.
            """
            author_obj = book_obj.cleaned_data.pop("authors")  # Take out the author field data that does not exist in the book table, and the objects stored in the list
            new_book_obj = models.Book.objects.create(**book_obj.cleaned_data)  # Create a table record in the Book table
            new_book_obj.authors.add(*author_obj)  # Find the third table and store the relationship between the book and the author
            """
            return HttpResponse("Book created successfully")
        else:  # Illegal. Save the data back to the original location.
            return render(request, "create_book.html", {"book_obj": book_obj})
Front page create_book.html Writing method
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>


<div class="container-fluid">
    <div class="row">
        <div class="col-sm-6 col-sm-offset-3">
            <form action="" method="post" novalidate>  <!--novalidate Cancel the verification function of browser-->
            {% csrf_token %}
                {% for field in book_obj %}
                    {{ field.label }}
                    {{ field }}
                    {{ field.errors }}
                {% endfor %}
                <input type="submit">
            </form>
        </div>
    </div>
</div>


<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>

save() method of ModelFrom

Each ModelForm object also has a save() method. This method creates and saves database objects based on the data bound by the form.

The subclass object of ModelForm can accept the existing model instance as the keyword parameter instance;

  • If the ModelFrom object parameter specifies which book object instance is, the data of this book object will be updated;
  • If the ModelForm object parameter does not specify a Book instance object, a new book table record will be added to the obtained data.

save creates a record

def create_book(request):
    if request.method == "POST":
        form_obj = BookModelFrom(request.POST)
        if form_obj.is_valid():  # Return True if data validation is qualified, otherwise return False
            form_obj.save()  # form_obj object does not accept instance, here is create record
            return HttpResponse("Created successfully")
        else:
            return HttpResponse("Illegal data")

save update record

def create_book(request,n):  # n is to modify the id value of that book record, which is passed through the front end
    book_obj = models.Book.objects.filter(id=n)  # Find the book record to modify
    if request.method == "POST":
        form_obj = BookModelForm(request.POST,instance=book_obj)  # book_obj to BookModelForm object
        if form_obj.is_valid():
            form_obj.save()  # form_obj object accepts instance parameters. Here save is to update data to book_ In the record of obj
            return HttpResponse("Update successful")
        else:
            return HttpResponse("Illegal data") 

4. Use instance of modelform (create / update)

Create data to database

create_book.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>


<div class="container-fluid">
    <div class="row">
        <div class="col-sm-6 col-sm-offset-3">
            <form action="" method="post" novalidate>  <!--novalidate Cancel the verification function of browser-->
            {% csrf_token %}
                {% for field in book_obj %}
                    {{ field.label }}
                    {{ field }}
                    {{ field.errors }}
                {% endfor %}
                <input type="submit">
            </form>
        </div>
    </div>
</div>


<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>

View create_book function

def create_book(request):
    if request.method == "GET":
        book_obj = BookModelForm()  # Generate a book object from ModelForm
        return render(request, "create_book.html", {"book_obj": book_obj})  # The book object is passed to the front end for rendering
    else:
        data = request.POST
        book_obj = BookModelForm(data)  # Verify based on user data
        if book_obj.is_valid():  # Verify whether the data submitted by the user is consistent with the
            book_obj.save()  # Save the data to the corresponding table, because we have specified the table in Meta, so it can be recognized automatically. This sentence essentially completes the following three things.
            """
            author_obj = book_obj.cleaned_data.pop("authors")  # Take out the nonexistent field data and the objects in the list
            new_book_obj = models.Book.objects.create(**book_obj.cleaned_data)  # Create a table record in the Book table
            new_book_obj.authors.add(*author_obj)  # Find the third table and store the relationship between the book and the author
            """
            return HttpResponse("Book created successfully")
        else:  # Illegal. Save the data back to the original location.
            return render(request, "create_book.html", {"book_obj": book_obj})

Modify database data

Front page edit_book.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body>

<h1>Edit page</h1>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="{% url 'edit_book' n %}" novalidate method="post">
                {% csrf_token %}
                {% for field in form %}
                    <div class="form-group">
                        <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                        {{ field }}
                        <span class="text-danger">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}

                <div class="form-group">
                    <input type="submit" class="btn btn-primary pull-right">
                </div>

            </form>

        </div>
    </div>
</div>


</body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html>

View edit_book function

def edit_book(request,n):  # n is the id value of the front-end edited book in the database

    book_obj = models.Book.objects.filter(pk=n).first()  # Find the edited book object
    if request.method == 'GET':
        # all_authors = models.Author.objects.all()
        # all_publish = models.Publish.objects.all()  # After using ModelForm, you don't need to get all the author and publishing house information in this way. If a ModelForm object generates a label in the front end, it will be automatically recognized and generated.
        form = BookModelForm(instance=book_obj)
        return render(request,'edit_book.html',{'form':form,'n':n})  # The n parameter passed is used to submit data to the form form. It is used to identify which record is updated

    else:
        form = BookModelForm(request.POST,instance=book_obj)  # The instance must be specified, otherwise what we call the save method becomes the add operation
        if form.is_valid():
            form.save()
            return redirect('show')
        else:
            return render(request,'e

Tags: Django Database JQuery Attribute

Posted on Thu, 04 Jun 2020 08:02:53 -0400 by csj16