Skip to content

about

官网:https://django-debug-toolbar.readthedocs.io/en/latest/index.html

Django项目的开发过程中,离不开各种调试,那么,我们今天介绍一个工具,django debug toolbar,该工具为我们提供了更加丰富的调试信息,如提供session信息,SQL查询信息等等。 该插件配置简单,功能齐全,在调试中相当方便,而且灵活轻便。那么我们此次就通过一个django的demo来演示该插件的用法。

install

bash
# pip install django-debug-toolbar
pip install django-debug-toolbar==4.2.0

usage

来看具体配置,主要体现在settings.py、总路由urls.py中。

python
import debug_toolbar   # 必要的导入
from django.conf import settings  # 导入 settings
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('authapi/', include(('apps.authapi.urls', 'authapi'), namespace='authapi')),
    path('page/', include(('apps.mypage.urls', 'mypage'), namespace='mypage')),
]
# debug_toolbar这个工具是根据settings中的DEBUG来判断是否启用
if settings.DEBUG:
    urlpatterns.append(path('__debug__/', include(debug_toolbar.urls)), )
python
# 在本地调试的话,需要添加
INTERNAL_IPS = ['127.0.0.1', ]

# 在 INSTALLED_APPS 中配置
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',  # debug_toolbar要在django.contrib.staticfiles的下面
    'debug_toolbar',  # 配置debug_toolbar
    'apps.authapi',  # 用户认证相关的示例代码
    'apps.mypage',
]

# debug_toolbar的中间件尽可能的往前配置
# 注意,在中间件部分,如果你的中间件中有对响应内容进行编码的中间件,如GZipMiddleware,那么debug_toolbar的中间件要在这些中间件的后面。
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',  # debug_toolbar的中间件
    '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',
]
python
from django.db import models

class UserInfo(models.Model):
    num = models.CharField(max_length=32, verbose_name='序号', default=0)
    username = models.CharField(max_length=32, verbose_name='用户名')
    phone = models.CharField(max_length=11, verbose_name='手机号')
    email = models.EmailField(verbose_name='邮箱')

    def __str__(self):
        return f"{self.num}-{self.username}"
python
from django.shortcuts import render
from django.http.response import JsonResponse
from django.core.paginator import Paginator, InvalidPage, PageNotAnInteger, EmptyPage
from apps.mypage.models import UserInfo
from apps.mypage.pager import MyPaginator1, MyPaginator2, MyPaginator3

def userlist1(request):
    paginate_by = 10  # 每页展示的记录条数
    current_page = request.GET.get('page')  # 获取url上的页码
    queryset_count = UserInfo.objects.order_by('id').count()
    page_info = MyPaginator1(current_page, queryset_count, paginate_by, '/page/userlist1/', 11)
    user_list = UserInfo.objects.order_by('id')[page_info.start(): page_info.end()]
    return render(request, 'userlist1.html', {'user_list': user_list, 'page_info': page_info})
python

from django.core.paginator import Paginator
class MyPaginator1(object):
    """ 自定义分页器类,和内置分页器就没关系了,所有逻辑我们自己实现 """

    def __init__(self, current_page, all_count, per_page, base_url, show_page=11):
        """
        :param current_page:
        :param all_count: 数据库总行数
        :param per_page: 每页显示函数
        :return:
        """
        self.per_page = per_page
        a, b = divmod(all_count, per_page)
        if b:
            a = a + 1
        self.all_pager = a
        self.show_page = show_page
        self.base_url = base_url
        try:
            self.current_page = int(current_page)
            if not (1 <= self.current_page <= self.all_pager):
                self.current_page = 1
        except Exception as e:
            self.current_page = 1
    def start(self):
        return (self.current_page - 1) * self.per_page

    def end(self):
        return self.current_page * self.per_page

    def pager(self):
        page_list = []
        half = int((self.show_page - 1) / 2)
        # 如果数据总页数 < 11
        if self.all_pager < self.show_page:
            begin = 1
            stop = self.all_pager + 1
        # 如果数据总页数 > 11
        else:
            # 如果当前页 <=5,永远显示1,11
            if self.current_page <= half:
                begin = 1
                stop = self.show_page + 1
            else:
                if self.current_page + half > self.all_pager:
                    begin = self.all_pager - self.show_page + 1
                    stop = self.all_pager + 1
                else:
                    begin = self.current_page - half
                    stop = self.current_page + half + 1

        if self.current_page <= 1:
            prev = "<li class='disabled'><a href='#'>上一页</a></li>"
        else:
            prev = "<li><a href='%s?page=%s'>上一页</a></li>" % (self.base_url, self.current_page - 1,)
        page_list.append(prev)

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

        if self.current_page >= self.all_pager:
            nex = "<li class='disabled'><a href='#'>下一页</a></li>"
        else:
            nex = "<li><a href='%s?page=%s'>下一页</a></li>" % (self.base_url, self.current_page + 1,)
        page_list.append(nex)

        # 首页
        first = "<li><a href='%s?page=%s'>首页</a></li>" % (self.base_url, 1)  # 第一页写死一个1就好了
        page_list.insert(0, first)
        # 尾页
        last = "<li><a href='%s?page=%s'>尾页</a></li>" % (self.base_url, self.all_pager)  # 最大页码是self.all_pager
        page_list.append(last)
        return ''.join(page_list)
html
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-lg-offset-2">
            <h1>用户列表</h1>
            <h1>用户列表</h1>
            <!-- 如果有分页对象中数据就for循环展示数据 -->
            {% if user_list %}
                <table class="table table-bordered table-hover">
                    <thead>
                    <tr>
                        <th>序号</th>
                        <th>姓名</th>
                        <th>手机号</th>
                        <th>邮箱</th>
                    </tr>
                    </thead>
                    <tbody>
                    <!-- 如果有数据就for循环queryset展示数据 -->
                    {% for user in user_list %}
                        <tr>
                            <td>{{ user.num }}</td>
                            <td>{{ user.username }}</td>
                            <td>{{ user.phone }}</td>
                            <td>{{ user.email }}</td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            {% else %}
                <div>
                    <div class="alert alert-warning" role="alert">没有数据!</div>
                </div>
            {% endif %}

            <nav aria-label="Page navigation">
                <ul class="pagination">
                    {{ page_info.pager|safe }}
                </ul>
            </nav>

        </div>
    </div>
</div>
</body>
</html>
python
import os
import django
import faker


os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dj42.settings")  # dj42:项目名称
django.setup()  # 这一步就加载了Django环境

# 必须是django.setup()之后,才能引入模型类
from apps.mypage.models import UserInfo

fk = faker.Faker(locale='zh_CN')  # locale='zh_CN' 中文  locale='en_US' 默认美式英文

def foo():
    data_list = [
        UserInfo(num=i, username=fk.name(), phone=fk.phone_number(), email=fk.email())
        for i in range(1, 1000000)
    ]
    UserInfo.objects.bulk_create(data_list)

if __name__ == '__main__':
    foo()

现在,就可以正常的启动Djando,进行访问了,在页面的右侧就是django-debug-toolbar的展示效果,你可以点击具体的某一项来观察其细节。

1832669386729586688.png