Django basics - routing controllers and views (Django-02)

a routing controller

Reference link: Django source code reading: Routing (2) - Zhihu

Route routing is a mapping relationship! Routing is a relationship that binds and maps the URL path  requested by the client  to the view.

This /timer is finally matched to the view function timer in myapp.views through the routing controller .

All routes in Django are ultimately saved to a variable urlpatterns, and urlpatterns must be declared in the total route of urls.py under the main application . This is set by the configuration file settings.

When Django is running, when the client sends an http request to the server, the server's web server will extract the URL address from the http protocol, and find the URLs of all the routing information added to the urlpatterns in the project from within the program for traversal matching. . If they are equal or the match is successful, the view method of the current url object is called.

In the process of adding routes to the urlpatterns route list, Django provides a total of 2 functions for developers to register routes, string routing and regular routing .

from django.urls import path      # 字符串路由
from django.urls import re_path   # 正则路由,会把url地址看成一个正则模式与客户端的请求url地址进行正则匹配

# path和re_path 使用参数一致.仅仅在url参数和接收参数时写法不一样

1.1 Basic use

The use of path and re_path two routes:

# 只要请求路径和正则匹配成功就会执行视图函数~
path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/([0-9]{4})/$', views.year_archive),# $ 符 不会被上面的覆盖掉 上面的就匹配不成功了
# 1、简单分组 ([0-9]{4})  ([0-9]{2})  是按位置传参的 和参数位置有关
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),#加个小括号是正则的简单分组 符合小括号的正则内容 会按形参入到视图函数中 函数也要接收~

# 2、有名分组 ?P<year>  ?P<month> 是按关键字传参的 和参数位置无关 视图函数形参的参数名要保持一直
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive2),

'''
re_path(r'^articles/(\d{4}/(\d{1,2})/$',articles_archive_by_month)
请求路径:/articles/2010/12
# 简单分组
re.findall("articles/(\d{4}/(\d{1,2})","/articles/2010/12") # 左边是规则 后面是请求路径 
一旦匹配成功:调用articles_archive_by_month(request,2010,12) # (\d{4}/(\d{1,2})分组了 就会传参 视图函数就会在数据库里进行查询

# 有名分组
一旦匹配成功:
if 简单分组:
    调用articles_archive_by_month(request,2010,12)  # 位置传参
else if 有名分组:
    调用articles_archive_by_month(request,year = 2010,month = 12) # 关键字传参
'''

1.2 Route distribution

from django.urls import path, re_path, include

path('api/', include('erp_system.urls')),
path('api/', include('basic_info.urls')),
path('api/', include('goods_info.urls')),
path('api/', include('purchase_info.urls')),
path('api/', include('warehouse_info.urls')),

1.3 Reverse analysis

When working with Django projects, a common need is to obtain the final form of a URL, either for embedding into generated content (URLs displayed in views and to the user, etc.) or for handling server-side navigation (redirects, etc. ) . There is a strong desire  not to hardcode these URLs (laborious, unscalable, and error-prone) or to design a specialized URL generation mechanism that has nothing to do with URLconf, because this will easily lead to a certain degree of stale URLs.

Reverse analysis: I don’t want to write the route to death

Where a URL is required, Django provides different tools for URL inversion at different levels:

In the template: use url template tag

In Python code: use from django.urls import reverse function. (When writing url in view function redirection)

Set alias parameters for url in urls.py:

from django.conf.urls import url
from . import views

urlpatterns = [
    #...name='news-year-archive'
    url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
    #...
]

Apply reverse parsing in the template: {% url 'news-year-archive' 2012 %} Alias: 'news-year-archive' Regular parameters: 2012.

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
<a href="/articles/2012/">2012 Archive</a>
from django.shortcuts import redirect
from django.urls import reverse

def redirect_to_year(request):
    year = 2006
    reverse_path=reverse('news-year-archive', args=(year,))
    return redirect(reverse_path)  # 等效 redirect("/articles/2006/")

two views

There are two main types of views in Django, namely view functions and view classes . Now we will start with view functions (FBV) and then learn about view classes (CBV).

  • Function BaseView: function base view

  • Class BaseView: class base view

2.1 Request method

The web project runs under the http protocol, and by default it certainly supports users to send data through different http requests. Django supports allowing clients to access project views only through specified HTTP requests.

home/views.py

# 让用户发送POST才能访问的内容
from django.views.decorators.http import require_http_methods
@require_http_methods(["POST"])
def login(request):
    # 获取请求方式 GET/POST
    print(request.method)
    # 获取请求体数据
    print(request.body) # 一个字符串,代表请求报文的请求体的原数据
    print(request.POST) # 只有请求数据格式是 urlencoded 时才能获取到
  
    # 获取具体数据
    user = request.POST.get("user")# get()获取键对应值的列表里的最后一个元素
    hobby = request.POST.getlist("hobby")# 获取值列表里的所有元素
    return HttpResponse("登录成功!")

Route binding,demo/urls.py ,code:

from django.contrib import admin
from django.urls import path
from home.views import timer
urlpatterns = [
    path('admin/', admin.site.urls),
    path("timer", timer),
    path("login", login),
]

2.2 Request object

Django encapsulates the request line, header information, and content body in the request message into attributes in the HttpRequest class. Unless otherwise specified, everything else is read-only.

The HttpRequest object contains some information about the current request URL:

# 进入注册页面的视图函数
@require_http_methods(["GET"])
def register(request):
    print('进入register视图函数')
    user_id = request.GET['id']
    print(user_id, type(user_id))
    return HttpResponse(f'你传入的用户ID是:{user_id}')

2.2.1 Request method

print(request.method)

2.2.2 Request data

1.  HttpRequest.GET : A dictionary-like object that contains all parameters of HTTP GET. Please refer to the QueryDict object for details.

2. HttpRequest.POST : A dictionary-like object. If the request contains form data, the data is encapsulated into a QueryDict object. # Note: When the value of the key-value pair is multiple, # such as checkbox type input tag, select tag, you need to use: request.POST.getlist("hobby").
3.  HttpRequest.body : A string representing the original data of the request body of the request message.

2.2.3 Request path

HttpRequest.path : Indicates that the path component of the request (excluding get parameters) is only the path part.
HttpRequest.get_full_path() : Path containing get parameters.

2.2.4 Request header

HttpRequest.META : A standard Python dictionary containing all HTTP headers. The specific header information depends on the client and server, HttpRequest.META.get('HTTP_HOST').

2.3 Response object

There are three main forms of response objects:

HttpResponse () # Response base class
JsonResponse () # Response in json format (interface programming, DRF)

render () # The core is HttpResponse()

redirect () # The kernel is HttpResponse()

2.3.1 HttpResponse()

After receiving the request from the client, the Django server will encapsulate the submitted data into an HttpRequest object and pass it to the view function. Then the view function also needs to return a response to the browser after processing the relevant logic.

For this response, we must return an object of HttpResponseBase or its subclass . HttpResponse is the most commonly used subclass of HttpResponseBase.

return HttpResponse("登录成功!",status=404,content_type='text/plain')

Common properties:

content : the returned content.

status_code : The returned HTTP response status code.

content_type : MIME type of the returned data, default is text/html. The browser will display data based on this attribute. If it is text/html, then the string will be parsed, if text/plain, then a plain text will be displayed.

Set response header: response['X-Access-Token'] = 'xxxx' .

2.3.1.2 JsonResponse class:

Used to dump the object into a json string, and then return the json string to be encapsulated into a Response object and returned to the browser. And its Content-Type is application/json. The sample code is as follows:

from django.http import JsonResponse

def index(request):
    book = {"title":"三国演义","price":199}
    books = [{"title":"三国","price":99},{"title":"三国演义","price":199}]
    # JsonResponse(book)本质 是先序列化json.jump, ensure_ascii=False 使数据正常显示 。content_type='application/json' 声明一下响应类型
    # return HttpResponse(json.jump(book,ensure_ascii=False),content_type='application/json')
    # return JsonResponse(book) # 默认是序列化一个字典
  
    return JsonResponse(books,safe=False) # 序列化一个非字典数据(列表)

By default, JsonResponse can only dump dictionaries. If you want to dump non-dictionary data, you need to pass a safe=False parameter to JsonResponse.

2.3.2 render() rendering function

render(request, template_name,[context])
#结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。\
render(request,'users/index.html',['ip':2013])

parameter:

/*
 request: 用于生成响应的请求对象。ip
 template_name:要使用的模板的完整名称,可选的参数。模板文件非html文件因为里面有模板语句{
   
   {ip}},渲染后呈现在浏览器中的才是htm页面
 context:添加到模板上下文的一个字典,
          默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
 */

The render method is to render the template syntax in a template page and finally render it into an html page as the response body.

2.3.3 redirect method (redirect)

When you build a Python web application using the Django framework, you at some point have to redirect the user from one URL to another , using the redirect method.

Parameters can be:

  • An absolute or relative URL, which will be used unchanged as the redirect location.

  • Alias ​​of a url: You can use reverse to reversely parse the url

# 传递要重定向到的一个具体的网址
def my_view(request):
    ...
    return redirect("/some/url/")
# 当然也可以是一个完整的网址
def my_view(request):
    ...
    return redirect("http://www.baidu.com")
# 传递一个视图的名称
def my_view(request):
    ...
    return redirect(reverse("url的别名"))

There will be two requests for redirection. The first one will return a response header location:/index/ (/index/ is the relative path written in redirect) code: 301. As long as the browser reads 301 or 302, it will initiate a new request. Return an index.html page twice.

The implementation of APPEND_SLASH is based on redirect. By default, the browser request path is supplemented by /. Configuring APPEND_SLASH=False in the setting file will turn off the supplement by default.

Three login verification cases

3.1 html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

/*/users/auth 相对路径一定要加第一个/*/
<form action="/user/auth" method="post">
    用户名<input type="text" name="user">
    密码 <input type="password" name="pwd">
    /*span标签提示错误信息*/
    <input type="submit"> <span style="color: red">{
   
   { msg }}</span>
</form>
</body>
</html>

3.2 Routing configuration

from django.contrib import admin
from django.urls import path, re_path,include

from users.views import login,auth
urlpatterns = [
    path("login",login),
    path("auth",auth),
]

3.3 View functions

def login(request):
    return render(request,"login.html")

def auth(request):
    #  获取数据
    print("request.POST:",request.POST)

    user = request.POST.get("user")
    pwd = request.POST.get("pwd")

    # 模拟数据校验
    if user == "laomao" and pwd == "123456":
        # return HttpResponse("验证通过")
        return redirect("/users/")
    else:
        # return HttpResponse("用户名或者密码错误")
        # return redirect("/users/login")
        # 重定向适合动态页面 静态页面可以用render
        # 静态页面渲染一些信息一般用render
        msg = "用户名或者密码错误"
        return render(request,"login.html",{"msg":msg})

Guess you like

Origin blog.csdn.net/March_A/article/details/133501212