Django日志-中间件-分页-上传图片

作者: 鲁智深 分类: django 发布时间: 2018-01-17 19:54

Django 使用Python 内建的logging 模块打印日志。

每个logger 都有一个日志级别。日志级别表示该logger 将要处理的消息的严重性

日志级别:

DEBUG:用于调试目的的底层系统信息

INFO:普通的系统信息

WARNING:表示出现一个较小的问题。

ERROR:表示出现一个较大的问题。

CRITICAL:表示出现一个致命的问题

常用的在可控制台输出日志系统,查询sql语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

中间件

概念:它是一个轻量级、底层的“插件”系统,用于在全局修改Django 的输入或输出。

特点:

支持热插拔,也就是插上就能用

是一套钩子框架,可以介入Djangode 请求和响应的处理过程

有很多中间件,每个负责某个特定的功能

不是必需品的

顺序非常重要,因为可能互相依赖

调用的顺序

调用的顺序

分为两个阶段:

在请求阶段中,调用视图之前,Django会按照MIDDLEWARE_CLASSES中定义的顺序自顶向下应用中间件

主要实现了两个方法:process_request、process_view

process_request:request是一个HttpRequest 对象。在Django决定执行哪个视图之前,process_request()会在每个请求上调用。返回一个None 或一个HttpResponse对象。如果返回None,Django会继续处理这个请求,执行其它process_request()中间件,然后process_view()中间件,最后是对应的视图。如果它返回一个HttpResponse对象,Django 就不用再去调用其它的request、view 或exception 中间件,或对应的视图;它将对HttpResponse 运用响应阶段的中间件,并返回结果

process_view:会在Django 调用视图之前被调用。返回None 或一个HttpResponse 。如果返回None,Django 将会继续处理这个请求,执行其它的process_view() 中间件,然后调用对应的视图如果返回一个HttpResponse对象,Django 就不用再去调用其它的中间件,或对应的视图;它将对HttpResponse 运用响应阶段的中间件,并返回结果。

在响应阶段中,调用视图之后,中间件会按照相反的顺序应用,自底向上。会用到三个钩子主要实现两个方法:process_template_response(仅用于模板相应)、process_response

process_template_response:由Django视图或者中间件返回。须返回一个实现了render方法的响应对象。

process_response:在所有响应返回浏览器之前被调用,必须返回HttpResponse或者StreamingHttpResponse对象。

异常的处理: process_exception():无论是请求阶段还是响应节段只要抛出异常就会调用

案例判断浏览器来源

在settings.py 中添加到MIDDLEWARE中

1
2
3
4
5
6
7
8
9
10
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',
    'myblog.Mymiddleware.CheckSourceMiddle',
]

在应用目录下创建 Mymiddleware.py

1
2
3
4
5
6
7
8
9
10
# coding: utf-8
from django.utils.deprecation import MiddlewareMixin
class CheckSourceMiddle(MiddlewareMixin):
    def process_request(self, request):
        from_source = request.META['HTTP_USER_AGENT']
        print('from_source', from_source)
        if 'iphone' in from_source:
            request.session['from_source'] = 'iphone'
        else:
            request.session['from_source'] = 'PC'

在应用视图中下创建 index函数

1
2
3
4
5
def index(request):
    from_source = request.session.get('from_source')
    mesg = '你来哪里 %s '%from_source
    centext = {'mesg':mesg}
    return render(request, 'store/index.html',centext)

分页

Paginator对象

Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True), 返回分页对象
必须参数:
object_list,列表或元组,
per_page: 每页展示的数据的条数
可选:Allow_empty_first_page: 是否让第一页可以显示空
方法:Paginator.page(number) 返回Page对象,下标以1开始。如果提供的页码不存在,抛出InvalidPage异常
属性:
count:所有页面的对象总数
num_pages页面总数
page_range页码的范围,从1开始,例如[1, 2, 3, 4]

InvalidPage异常:

InvalidPage:当paginator传入一个无效的页码时抛出
PageNotAnInteger:当向page()提供一个不是整数的值时抛出
EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出

Page对象

创建对象
Paginator对象的page()方法返回Page对象,不需要手动构造

属性
object_list:当前页上所有对象的列表
number:当前页的序号,从1开始
paginator:当前page对象相关的Paginator对象

方法
has_next():如果有下一页返回True
has_previous():如果有上一页返回True
has_other_pages():如果有上一页或下一页返回True
next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
len():返回当前页面对象的个数
迭代页面对象:访问当前页面中的每个对象

路由

1
url(r'^page', views.page),

视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def page(request):
    pageall = Article.objects.all()
    Paginator1 = Paginator(pageall,2)
    page_num = request.GET.get('page')

    try:
        rows = Paginator1.page(page_num)
    except PageNotAnInteger:
        rows = Paginator1.page(1)
    except EmptyPage:
        rows = Paginator1.page(Paginator1.num_pages)

    centext = {'rows':rows}
    return render(request,'myblog/page.html',centext)

模版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for row in rows %}
    {{ row }}<br>
{% endfor %}

{% if rows.has_previous %}
    <a href="?page={{ rows.previous_page_number }}">上一页</a>
{% endif %}

{% for rpage in rows.paginator.page_range %}
    <a href="?page={{ rpage }}">{{ rpage }}</a>
{% endfor %}
{#{{ rows.number }}/{{ rows.paginator.num_pages }}#}
{% if rows.has_next %}
    <a href="?page={{ rows.next_page_number }}">下一页</a>
{% endif %}
</body>
</html>

上传图片

配置文件页面中上传图片 全局

1
2
MEDIA_URL = '/images/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images/')

添加一个ImageField字段

1
img = models.ImageField(verbose_name='图片', upload_to='images/')

路由

1
url(r'^editor/$', views.editor_page,name='editor'),

视图函数

1
2
3
4
5
6
7
8
9
def editor_page(request):
    if request.method == 'POST':
        # 获取传过来的图片
        username = request.POST.get('blog_user')
        email = request.POST.get('email')
        password = request.POST.get('password')
        img = request.FILES.get('file')
        User(username=username,email=email,password=password,img=img).save()
    return render(request, 'store/editor.html')

模版代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
    <form method="POST" enctype="multipart/form-data" action="{% url 'reverese:editor' %}"><br>
        {% csrf_token %}
    作者:<input type="text" name="blog_user" placeholder="作者"><br/>
    邮箱:<input type="email" name="email"><br>
    密码:<input type="password" name="password"><br>
    图片:<input type="file" name="file"><br>
        <input type="submit" value="提交"><br>
</form>

</body>
</html>

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注