Django component summary

Introducing Django

  1. Use finisher

Paging is very common on the page, when excessive number of database data, page one-time display does not look good, we can use a pager, the data show several times.

Inserting large amounts of data within the database 1.1
Booklist=[]
for i in range(100):
    Booklist.append(Book(title="book"+str(i),price=30+i*i))
Book.objects.bulk_create(Booklist)

Using the following objects bulk_create()can be inserted in batches

1.2 import module

from django.core.paginator import Paginator

Examples of a pager 1.3

paginator = Paginator (book_list, 8) a first list of data, second data for each page

1.4 pager objects related to a method
方法                                  作用
paginator.count()                   数据总数
paginator.num_pages()               总页数
paginator.page_range()              页码的迭代器

N obtain data page
current_page = paginator.page(1)to get a list of the first page


方法                                            作用
current_page.object_list                     获取第n页对象列表
current_page.has_next()                      是否有下一页
current_page.next_page_number()              下一页的页码
current_page.has_previous()                  是否有上一页
current_page.previous_page_number()          上一页的页码

Note: If the number of pages in the input paginator.page (1) is less than 1 or greater than the maximum number of pages, an error will be reported EmptyPage.
Capture EmptyPage wrong way

from django.core.paginator import EmptyPage
introduce errors, use try catch error

try:
   内容
except EmptyPage as e:
    current_page=paginator.page(1)
A simple example of paging 1.5

views.py in

def books(request):
    book_list = Book.objects.all()
    from django.core.paginator import  Paginator,EmptyPage
    paginator = Paginator(book_list,3)
    num_pages = paginator.num_pages
    current_page_num = int(request.GET.get("page",1))
    if num_pages > 11:
        if current_page_num < 5:
            page_range = range(1,11)
        elif current_page_num+5 > num_pages:
            page_range = range(num_pages-10,num_pages+1)
        else:
            page_range = range(current_page_num-5,current_page_num+5)
    else:
        page_range = paginator.page_range
    try:
        current_page = paginator.page(current_page_num)
    except EmptyPage as e:
        current_page = paginator.page(1)
    return render(request,"book.html",locals())

book.html in

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>分页练习</title>
   <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
   <script
           src="https://code.jquery.com/jquery-3.3.1.js"
           integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
           crossorigin="anonymous"></script>
</head>
<body>
<p>OK</p>
<table class="table table-striped">
   <tbody>
{#显示当前页面#}
   {% for book in current_page %}
       <tr>
           <td>{{ book.nid }}</td>
           <td>{{ book.title  }}</td>
           <td>{{ book.price}}</td>
       </tr>
   {% endfor %}
   </tbody>
</table>
{#显示页码#}
<ul class="pagination">
   {% if current_page.has_previous %}
       <li>
           <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
               <span aria-hidden="true">&laquo;</span>
           </a>
       </li>
   {% else %}
       <li class="disabled">
           <a href="" aria-label="Previous">
               <span aria-hidden="true">&laquo;</span>
           </a>
       </li>
   {% endif %}

   {% for item in page_range %}
       {% if item == current_page_num %}
           <li class="active"><a href="?page={{ item }}">{{ item }}</a></li>
       {% else %}
           <li><a href="?page={{ item }}">{{ item }}</a></li>
       {% endif %}
   {% endfor %}

   {% if current_page.has_next %}
   <li>
       <a href="?page={{ current_page.next_page_number }}" aria-label="Next">
           <span aria-hidden="true">&raquo;</span>
       </a>
   </li>
   {% else %}
   <li class="disabled">
       <a href="" aria-label="Next">
           <span aria-hidden="true">&raquo;</span>
       </a>
   </li>
   {% endif %}
</ul>

</body>
{#<script>#}
{#    $(".pagination li a").click(function () {#}
{#        $(this).parent().addClass("active").siblings("li").removeClass("active")#}
{#    })#}
{#</script>#}
</html>
  1. forms component

component forms the main function is the function of the field test, check the form of the function key

2.1 Inspection field function
2.11 Importing forms assembly

from django import forms

2.12 using forms to create a component class
class UserForm(forms.Form):
    name = forms.CharField(min_length=4)
    email=forms.EmailField()

name field a minimum of not less than four bytes, email field must mail format
Note: This class must inherit forms.Form
only check UserForm in the field, passed in other fields will be ignored and will not check. The field forms exist, when the check field can not be blank

Some commonly used functions and their parameters check

Check function

  • CharField check character string, you may be provided a minimum length or a maximum length max_length min_length

  • DecimalField digital authentication verification, trailing spaces are ignored, and MAX_VALUE min_value control overall length, and should be given as decimal.Decimal value. + max_digits allows decimal integer total number of bits;

  • Decimal_places maximum allowable number of decimal places.

  • EmailField is a valid e-mail address, and optional parameters max_length min_length

  • Are FileField non-empty file data is bound to the form, whether max_length maximum file size and file can be empty allow_empty_file

  • FloatField Verify whether a given value float, max_value and optional min_value

  • IntegerField verify whether a given value is an integer. Alternatively max_value and MIN_VALUE
    2.13 instantiate objects forms a

    将需要验证的表单值传入,检验是否合法
    form=UserForm({"name":"yuan","email":"123"})
    也可以直接传入POST字典(但是前段键值必须与form一一对应)
    form = UserForm(request.POST)
2.14 View check field results

Related API

  • form.is_valid () by checking all return True, otherwise False
  • form.cleaned_data return to the dictionary, you can check to see successful field (keys are placed)
  • form.errors can see the field of validation errors (error checking key for the key, the value of the error message list)
    2.15 rendering tagging
    forms component can also automatically render the form check field for us in the form form

Specific methods are as follows

2.16 forms a first class to instantiate

form = UserForm () do not pass the value

2.17 use forms in a template

Method 1: Use labels {. {Form field}} can render the corresponding input tag
in HTML

<form action="" method="post">
    {% csrf_token %}
    <p>用户名:{{ form.name }}</p>
    <p>密码:{{ form.pwd }}</p>
    <p>再次确认密码:{{ form.re_pwd }}</p>
    <p>邮箱:{{ form.email }}</p>
    <p>电话:{{ form.tel }}</p>
    <input type="submit" value="注册">
</form>    

In view function
form the UserForm = ()
Forms component will automatically generate tag name attribute becomes the name of the corresponding field
for example

Username: {{form.name}}


Equivalent to

username:

Second way: using a for loop labels

<form action="" method="post">
    {% csrf_token %}
    {% for field in form %}
        <p>
            <label>{{ field.label }}</label>
            {{ field }} <span>{{ field.errors.0 }}</span>
        </p>
    {% endfor %}
    <input type="submit" value="注册">
</form>

Use {. {Form field .label}} can render the corresponding label should
note: label tag field name is displayed by default, if you want to display the content of the label should be specified when creating forms class

class UserForm(forms.Form):
    name = forms.CharField(min_length=4,label="用户名")
    email=forms.EmailField(label="邮箱")

Using the label specified parameters, rendering the effect is equivalent to using this UserForm

<p>用户名:{{ form.name }}</p>  
<p>邮箱:{{ form.email }}</p>
<p>方式三</p>
<form action="" method="post">
    {% csrf_token %}
    {{ form.as_ul }}
    <input type="submit" value="注册">
</form>

Using {{form.as_ul}} automatically render all fields, and each field input using the label rendering ul and treated with wrap
may also be selected by as_p (), as_table () respectively with p, table package label

2.2 reset the display interface forms

When the user form input errors, we may pass their own parameters, set the value of the value of each input, reset to render a page, using the forms component can quickly render a reset interface
simply by setting a few steps

def register(request):
    if request.method =="POST":
        form = UserForm(request.POST)
        if form.is_valid():
            return HttpResponse("ok")
        else:
            return render(request,"register.html",locals())
    else:
        form = UserForm()
        return render(request,"register.html",locals())

Simply put, if the user accessed using a browser page, send a get request, we use the form = UserForm () forms an object passing in a no parameters, the browser will automatically render a blank label each field
if the user when the form is submitted, we instantiate a form = UserForm (request.POST) forms an object with parameters, the same, the browser will render the contents of the parameters passed to submit the form.
In other words, when an input error, the contents of the form returned by the user input is not empty, it is the last time the user entered the wrong content

2.3 How to display an error message

If we want to verify data after the input error information to the HTML page, we can do this

2.31 First instance of the object passed in HTML forms
form = UserForm()
return render(request,"register.html",locals())

Thus when all the local variables directly mapped to an HTML template (including the form)

2.32 calls the corresponding objects in the HTML template
<form action="" method="post">
    {% csrf_token %}
    <p>用户名:{{ form.name }}<span>{{ form.name.errors.0 }}</span></p>
    <p>密码:{{ form.pwd }}<span>{{ form.pwd.errors.0 }}</span></p>
    <p>再次确认密码:{{ form.re_pwd }}<span>{{ form.re_pwd.errors.0 }}</span></p>
    <p>邮箱:{{ form.email }}<span>{{ form.email.errors.0 }}</span></p>
    <p>电话:{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p>
    <input type="submit" value="注册">
</form>

Using {{form. Tag field .errors.0}} if the corresponding field error, can render an appropriate error message ({{form. .Errors}} field is a list of errors, we use a {{form. Field .errors. 0}} only take the first error message)

2.4 forms of configuration parameters

Use widgets module, we can set the parameter field to the corresponding forms of the class

2.41 import module

form django.forms import widgets

2.42 assembly forms the element type is provided in the template generated

If we set a field to check CharField type, then generate tags in the HTML template that isType
If we want to change the type of label generation, how do?
Example:

pwd =forms.CharField(min_length=4,widget=widgets.PasswordInput())
使用widget参数可以设置标签类型,PasswordInput()代表将自动生成```类型标签
2.43 assembly forms generated attribute setting element in the template

If we want to each element of the generated add some default attributes, we can use the element types attrs parameter function
example: name = forms.CharField (min_length = 4 , widget = widgets.TextInput (attrs = { "class" : "form-control"}) )
is added to each element in the default class attribute generated, is form-control
by attrs setting key stored in need of

2.5 check local hooks

If the above conditions checksum field is too small, can not meet our needs, we can customize the content of the check, it is necessary for each field using local hook
use

2.51 Principle

When we call s_valid under the forms objects () function, will conduct field verification; check successfully placed clean_data dictionary, the check fails throwing an exception, an exception handler will then check failed field and an error message store the errors dictionary. And when the verification is successful django, deliberately leaving a hook, for a user-defined function
django part of the code:

if hasattr(self, 'clean_%s' % name):
    value = getattr(self, 'clean_%s' % name)()
    self.cleaned_data[name] = value
2.52 first import the type of error
from django.core.exceptions import ValidationError
ValidationError是用来抛出异常时的错误类型
2.53 and then create a function clean_ field in the forms of class

def clean_name(self):

2.54 cleaned_data acquired successfully verified using the value of

val = self.cleaned_data.get ( "name")
using cleaned_data can get validation success Dictionary

Example 2.55

Verify that the phone number field is eleven

def clean_tel(self):
    val = self.cleaned_data.get("tel")
    if len(val)==11:
        return val
    else:
        raise ValidationError("手机号位数错误")

Remove the check from the forms of success phone number, verify them, if the conditions are met, the original out of the field as it is returned, otherwise an exception is thrown

2.6 Global hook

If we want the relationship between multiple fields for verification, such as a password and confirm the password require the same, but with only partial hook on the value of a single field for verification. This is the climate that we need a global hook
first step, the same types of errors introduced into ValidationError

2.61 Principle

django also leave a clean function, when the user wants the relationship between multiple fields for verification, direct overwrite this function, write the content they want to check in the function
django in part of the code
clean Code

def clean(self):
    """
    Hook for doing any extra form-wide cleaning after Field.clean() has been
    called on every field. Any ValidationError raised by this method will
    not be associated with a particular field; it will have a special-case
    association with the field named '__all__'.
    """
    return self.cleaned_data
2.62 Creating a clean forms function in class

def clean(self):

2.63 Example
checksum confirmation password and password are the same

def clean(self):
    pwd = self.cleaned_data.get("pwd")
    re_pwd = self.cleaned_data.get("re_pwd")
    if pwd and re_pwd:
        if pwd == re_pwd:
            return self.cleaned_data
        else:
            raise ValidationError("两次密码不一致")
    return self.cleaned_data

If the check is successful, return to the original clean_data field validation fails thrown ValidationError

Note: In the template, the error message single field validation fails, we can use the {{form field .errors}.}
The global hook thrown exception will be stored in the global error, we need to use clean_errors = form in python. errors.get ( " All ") acquired global error message using the template {{clean_errors.0}} to obtain error message
when we check also determines if pwd and re_pwd :, representative of a single field if the verification fails, not to perform a global hook. So if the password or confirm the password wrong format, password and confirmation is not the same, the only reported a password or password confirmation is incorrectly formatted.

  1. Middleware

##### 3.1 What is Middleware?

and the request handler between respone
the settings.py MIDDLEWARE the middleware stored in the array is

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'app01.my_middlewares.AuthMiddleware',
    'app01.my_middlewares.IpLimitMiddleware',
]

Middleware process
client - "wsgiref Module -" Middleware - "urls Routing Control -" Database MODEL, HTML templates

3.2 custom middleware

3.21 Create a folder to store intermediate, such as my_middlewares.py
3.22 import the corresponding class

from django.utils.deprecation import MiddlewareMixin
3.23 Creating the appropriate class (must inherit MiddlewareMixin)
class CustomerMiddleware(MiddlewareMixin)
    def process_request(self,request):
        print("Customer")

There must request parameter; do not return values, let it return to the default none

3.24 registered in the middleware MIDDLEWARE array

MIDDLEWARE = [
...
...
...
"app01.my_middlewares.CustomerMiddleware",
]
3.25 Middleware What is the role?
只要浏览器访问服务器,就会访问中间件
作用:大部分视图函数要使用的代码就可以放到中间件中
比如,将登陆函数放到中间件中,访问服务器就会调用中间件,验证是否登录
使用中间件限制用户访问的频率
3.26 The main method

In this class, you can define what a few main method

Method definition

  • process_request def process_request(self,request):
  • process_response def process_response(self,request,response):
  • process_view process_view(self, request, callback, callback_args, callback_kwargs)|
  • process_exception def process_exception(self,request,exception):
    注意:

Each class must pass the request parameter
process_response has to return, in response to body type (body passed respone parameter response function returns a view)
process_request If an intermediate return directly HttpRespone, does not perform the back middleware It will jump directly to the middleware 1

process_respone
process_exception not normally performed, are performed when the view given function; effect: yellow when given interface experience alternative response returned in the original function of the error corresponding to the capture exception, exception handling function
execution order
normally under:
process_request- "url controller -" process_view- "view function -" process_response
view when an error function
process_request- "url controller -" process_view- "view function error -" process_exception- "process_response

setting.py execution order list in MIDDLEWARE
when there are a plurality of intermediate, the server sends the data over the function performed sequentially from top to bottom, the function returns the view is sequentially performed from the bottom up
request process_request will pass over each client sequentially passed to the next process_request
each process_response to pass over the body in response to sequentially pass a process_response

E.g:

process_request1-》process_request2-》url控制器-》process_view1-》》process_view2-》视图函数出错-》process_exception2-》process_exception1-》process_response2-》process_response1
Example 3.3
3.31 plus a user authentication server page

If we want some pages only after the user logs show that we can use in addition to user authentication decorator decorator outside, you can also use the middleware

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
from authDemo import settings
class AuthMiddleware(MiddlewareMixin):
    def process_request(self,request):
        if request.path in settings.WHITE_LIST:
            return None
        #  用户登录验证
        if  not request.user.is_authenticated:
            return redirect("/login/")

settings.py which create a WHITE_LIST list, used to store the url does not require additional user authentication, such as login, registration, cancellation url
if the user is not logged, we will be redirected to the page / login /

3.32 IP access restrictions assessment rate

If we want to restrict access to the frequency of client ip, we can use the middleware

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
from authDemo import settings
import datetime

class IpLimitMiddleware(MiddlewareMixin):
    def process_request(self,request):
    if request.META.get("HTTP_X_FORWARDED_FOR"):
        ip = request.META["HTTP_X_FORWARDED_FOR"]
    else:
        ip = request.META["REMOTE_ADDR"]
    now_min = datetime.datetime.now().minute
    if ip in settings.BLACK_LIST:  #查询ip是否在黑名单内
        return HttpResponse("你已经被加入黑名单")
    elif ip in settings.IP_LIST:
        if settings.IP_LIST[ip]["min"] == now_min:
            settings.IP_LIST[ip]["times"] += 1
            if settings.IP_LIST[ip]["times"] >= settings.LIMIT_VISIT_TIMES:  #判断用户访问次数是否太快,返回提醒用户
                if settings.IP_LIST[ip]["times"] >= settings.MAX_VISIT_TIMES: #如果用户访问次数非常多,加入黑名单
                    settings.BLACK_LIST.append(ip)
                return HttpResponse("访问频率过快")
        else:
            settings.IP_LIST[ip]["times"] = 0
            settings.IP_LIST[ip]["min"] = now_min
    else:
        settings.IP_LIST[ip] = {"times":1,"min":now_min}
settings.py里创建一个IP_LIST字典,用来存储客户端ip和其他信息(其实可以单独放入数据库一个表中,不过从数据库中读取没有内存中读取快,访问速度会受到影响)
如果用户使用代理request.META["REMOTE_ADDR"]抓不到真实地址,所以我们首先使用request.META["HTTP_X_FORWARDED_FOR"]来获取用户真实地址
我们将其用户ip和访问次数储存,在settings.py中设置一个常量LIMIT_VISIT_TIMES,超过这个次数不让用户访问网页;MAX_VISIT_TIMES超过这个次数,将这个ip加入黑名单

Original link: https://blog.csdn.net/xgy123xx/article/details/82722185

Guess you like

Origin www.cnblogs.com/lzss/p/11922439.html