Summary of today's learning content 5.6

Summary of today's learning content

sweetalert front-end plug-in

    https://github.com/lipis/bootstrap-sweetalert

Serialization component

Component introduction

Import components

    from django.core import serializers

Introduction to components and usage parameters

    serializers.serialize('json', user_queryset)
    # The first parameter specifies the type to serialize
    # The second parameter is to specify the data to be serialized
    # The returned result is a list of serialized data in dictionary format

Code example

After the front-end and back-end separation, the queryset generated by django orm cannot be directly recognized by the front-end. It still needs json format data (hard currency).

    from django.core import serializers
    def dj_json(request):
        user_list = models.User.objects.all()
        res = serializers.serialize("json",user_list)
        return HttpResponse(res)

From the above code structure, we can find that the serializer converts objects into format strings, but the fields cannot be controlled. At this stage, if we want to serialize, we'd better use for loop + list dictionary; But this component will be used later in drf.

Batch data operation

Use for loop + list dictionary for serialization.

django is very slow to insert data into the database. When we need to insert a lot of data at one time, we need to optimize the data insertion. django inserts data through classes in models, so we first convert the data into corresponding classes, which can greatly save the process of converting corresponding table objects when django inserts the database, so as to greatly save the time of inserting data.

    def many_data(request):
        book_list = []
        for i in range(100000):
            # First generate an object with a class
            source_book_obj = models.Books(title=f'Number{i}This book')
            # Append object to list
            book_list.append(source_book_obj)
        models.Books.objects.bulk_create(book_list)  # Batch insert
        book_queryset = models.Books.objects.all()
        return render(request,'many_data.html',locals())

Pager

Introduction to pager

When the amount of data is very large, it is impossible for us to put all the data on the same page, so we have the concept of paging, which specifies how many pieces of data can be contained on each page like a book.

  1.all()The result set supports positive index slices

  2.Mathematical relationship of paging related parameters

  3.Back end rendering front end paging code

  4.Back end limit the number of paged displays

  5.When the page is less than 6 or greater than N All require additional restrictions

In the future, pagination may be used in many places, so it is impossible to write repeatedly, so it is encapsulated into modules.

Actual use

The custom pager module provided here needs to be used with bootstrap. You can also modify the style of pager and content display area by yourself. First, create a utils package. Create a py file and add the following code to it

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
        """
        Encapsulate paging related data
        :param current_page: Current page
        :param all_count:    Total number of data in the database
        :param per_page_num: Number of data pieces displayed per page
        :param pager_count:  Maximum number of page numbers displayed
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # Total page number
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # If total pages < 11:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # Total page > 11
        else:
            # If the current page is < = at most 11 / 2 page numbers are displayed on the page
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # The current page is larger than 5
            else:
                # Page number last
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # Add the previous nav and ul tags
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">home page</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#"> previous page < / a > < / Li > '
        else:
            prev_page = '<li><a href="?page=%s">previous page</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#"> next page < / a > < / Li > '
        else:
            next_page = '<li><a href="?page=%s">next page</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">Last page</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # Add label to tail
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

view layer:

from utils import mypage # Import the py file you just created
user_queryset = models.User.objects.all()
# 1. Generate pager object
'''For Pagination There are the following keyword parameters
current_page: Current page
all_count:    Total number of data in the database
per_page_num: Number of data pieces displayed per page
pager_count:  Maximum number of page numbers displayed
'''
page_obj = mypage.Pagination(current_page=request.GET.get('page'),all_count=user_queryset.count())

# 2. Generate paging data object
page_queryset = user_queryset[page_obj.start:page_obj.end]
return render(request,'many_data.html',locals())

Bootstrap template import:

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for user in page_queryset %}
            <p>{{ user.username }}</p>
            <p>{{ user.password }}</p>
            {% endfor %}
            {{ page_obj.page_html|safe }}
        </div>
    </div>
</div>

Forms component

application

It is generally used in the login and registration interface of the front end to verify the fields entered by the user, quickly judge whether the content entered by the user is legal, and return information.

Why not use JS directly at the front end for verification

    1. The verification of the front end can be omitted, But the back-end verification must have

    2. Because the front-end verification is weak, There are many ways to pass data by sending requests disguised as browsers

    3. Or the crawler can bypass the front-end page and submit data directly to the back-end

Basic use of forms component (steps)

    1. Import forms assembly

    2. Define a class, And inherit Form

    3. Write the field to be verified in the class, The attribute of the field is the rule to be verified

    4. Instantiate to get one Form object, Pass in the data to be verified

    5. call[form object].is_valid( )Method for verification, Verification passed return**True

    6. Check through call[form object].cleaned_data Obtain the verified data

    7. Verification failed call[form object].errors Get error message

Basic usage example of forms component

Common field properties

attribute interpretation
min_length Minimum length
max_length Maximum length
require This field must be filled in
label Label for this field
min_value Minimum number of digits
max_value Maximum number of digits

Write your own Forms:

    from django import forms
    class MyForm(forms.Form):
        # The user name must be at least three characters and at most eight characters
        username = forms.CharField(min_length=3,max_length=8, label="user name")
        # The minimum password cannot be less than 4 and the maximum password cannot exceed 16
        password = forms.CharField(min_length=6,max_length=16, label="password")
        # Mailbox must conform to mailbox format (@ key symbol)
        email = forms.EmailField(required=True, label="mailbox")

Check data

    	data = request.POST
    	# 1. Transfer data into instantiated object
        form_obj = MyForm({"username":data.get('username'), "password":data.get('password'), "email":data.get('email')}) # The data put into the corresponding dictionary can be directly passed in using * * data
        # 2. Check whether the data is legal (all legal results are True)
        form_obj.is_valid()
        # 3. Check the unqualified data and reasons
        form_obj.errors # Like this {'email': ['Enter a valid email address. ']}
        # 4. View qualified data
        form_obj.cleaned_data # Eligible data {'username': 'kdq', 'password': k12345}

Render Tag

Render mode 1

It has a high degree of encapsulation and poor scalability. It is mainly used to quickly generate page test functions.

<form action="" method="post" novalidate>
    {{ form.as_p }}       {# The display mode is the same as the previous two #}
    {{ form.as_ul }}      {# Front belt point #}
    {{ form.as_table }}   {# Show on one line #}
    <input type="submit" class="btn btn-block btn-success" value="register">
</form>

Render mode 2

Low encapsulation and good scalability, but it is inconvenient when there are many fields.

<form action="" method="post">
    <p>user name:{{ form.name }}</p>
    <p>password:{{ form.password }}</p>
    <p>Confirm password:{{ form.re_password }}</p>
    <p>mailbox:{{ form.email }}</p>
    <br>
    <input type="submit" class="btn btn-block btn-success" value="register">
</form>

Render mode 3

Using the for loop, the code is easy to write and has high scalability (recommended).

<form action="" method="post" novalidate>
    {% for foo in form %}
        <div class="form-group">
            {# Cyclic extraction name,password,re_password,email #}
            <p>{{ foo.label }}:{{ foo }}</p>
        </div>
    {% endfor %}
	<input type="submit" class="btn btn-block btn-success" value="register">
</form>

Display information

For the verification parameters filled in the forms class, the front-end browser will recognize and add verification operations. The verification operations of the front-end can be easily modified. It is best to verify at the back-end.

The form can cancel the operation of automatically adding verification function to the browser:

<form action="" method="post" novalidate></form> {# Just add novalidate Can not trigger forms Component validation #}

Front end acquisition method of error information:

{{ form.errors.0 }} 

Custom prompt:

Set error in the corresponding field_ Just messages

from django import forms
class MyForm(forms.Form):
    # The user name must be at least three characters and at most eight characters
    username = forms.CharField(min_length=3,max_length=8, label="user name", error_messages={
                         'min_length':'Minimum 3 digits of user name',
                          'max_length':'The maximum length of user name is 8 characters',
                          'required':'User name is required'
                               })
    # The minimum password cannot be less than 4 and the maximum password cannot exceed 16
    password = forms.CharField(min_length=6,max_length=16, label="password")
    # Mailbox must conform to mailbox format (@ key symbol)
    email = forms.EmailField(required=True, label="mailbox")


Posted by projectshifter on Sat, 21 May 2022 17:13:23 +0300