Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)

Django自带管理后台(admin)功能强大,几行配置即允许我们对模型数据进行过滤、筛选和增删改查,但是不够美观, 一般仅限内部使用。实际上使用Django自己开发管理后台并不复杂,本项目将演示如何使用django-filter和django-tables2打造功能性强且精美的管理后台,前端使用Boostrap 4。

项目演示效果

下图为Django自带admin对用户管理的界面。

Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)_第1张图片

下图是本例使用django-filterdjango-tables2打造的用户管理界面,是不是美观多了? 这个后台支持过滤、重置、按各种字段排序、分页等常见功能。

Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)_第2张图片

如果你还不过瘾,可以看下动画效果。

Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)_第3张图片

废话不多说,我们开始干吧。关注微信公众号【Python Web与Django开发】,发送消息【Django后台实战】,可以获取GitHub源码地址。

第一步 安装项目依赖

本项目所需的第三方安装包如下所示,均使用了最新版本,保证未来2-3年都不会过时,使用pip安装即可。

 Django==3.2.2
 django-filter==2.4.0 # 自定义过滤字段
 django-tables2==2.3.4  # 自定义表格显示字段
 django-widget-tweaks==1.4.8 # 用户美化表单

建议先创建虚拟环境再pip安装,如果你不会创建和激活虚拟环境,请先阅读https://pythondjango.cn/django/basics/2-installation-use/。

第二步 创建项目和应用

先使用django-admin startproject myproject创建一个名为myproject的应用,接着使用python manage.py startapp users创建一个名为users的app,并把它和其它三个项目依赖加入到settings.py的INSTALLED_APPS中去。

 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'widget_tweaks', # 项目依赖
     'django_tables2',# 项目依赖
     'django_filters',# 项目依赖
     'users', # 自建应用
 ]

然后把app下的urls路径加入到项目文件夹的urls.py里去。

 from django.contrib import admin
 from django.urls import path, include
 
 urlpatterns = [
     path('admin/', admin.site.urls),
     path('myadmin/', include('users.urls')) # 新增
 ]

整个项目的布局如下所示:

Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)_第4张图片

本例使用Django自带的User模型,无需创建模型,但考虑到后续存在切换自定义用户模型的可能性,我们使用get_user_model方法获取用户模型。

修改models.py, 添加如下代码:

 # users/models.py
 from django.contrib.auth import get_user_model
 
 User = get_user_model()

第三步 编写URLs和视图

users 目录下新建urls.py, 添加如下代码:

 # users/urls.py
 from django.urls import path, re_path
 from . import views
 
 app_name = "users"
 
 urlpatterns = [
     path('', views.UserAdminTableView.as_view(), name='user_admin'),
     path('users/create/', views.UserCreateView.as_view(), name='user_create'),
     path('users//update/', views.UserUpdateView.as_view(), name='user_update'),
     path('users//delete/', views.UserDeleteView.as_view(), name='user_delete'),
 ]
 

接下来编写与各个url路由对应的视图,它们位于user目录下views.py, 代码如下所示:

 # users/urls.py
 # 核心Django模块,比如Mixins和通用视图
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.views.generic import CreateView, UpdateView, DeleteView
 from django.urls import reverse_lazy
 from .models import User
 
 # django fitler和django_tables2提供的Mixins
 from django_tables2 import SingleTableView, RequestConfig
 from django_filters.views import FilterView
 
 # filters.py定义了用哪些字段对模型进行过滤
 from .filters import UserFilter
 
 # tables.py定义了用哪些字段将在表格中展示
 from .tables import UserTable
 
 # forms.py定义了用哪些字段创建或更新用户
 from .forms import UserForm
 
 # 管理用户主界面
 class UserAdminTableView(LoginRequiredMixin, SingleTableView, FilterView):
     filter = None
     # 使用UserFilter过滤
     filter_class = UserFilter
     # 使用UserTable展示数据
     table_class = UserTable
     template_name = 'users/user_admin.html'
 
     # 获取过滤后的查询集
     def get_queryset(self, **kwargs):
         qs = User.objects.all().order_by('-id')
         self.filter = self.filter_class(self.request.GET, queryset=qs)
         return self.filter.qs
 
     # 将查询集与table实例集合,提供filter和table两个变量前端渲染
     # 每页5条记录
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         t = self.table_class(data=self.get_queryset())
         RequestConfig(self.request, paginate={"per_page": 5}).configure(t)
         context['filter'] = self.filter
         context['table'] = t
         return context
 
 # create
 class UserCreateView(LoginRequiredMixin, CreateView):
     model = User
     template_name = 'users/user_form.html'
     form_class = UserForm
     success_url = reverse_lazy('users:user_admin')
 
 # update
 class UserUpdateView(LoginRequiredMixin, UpdateView):
     model = User
     template_name = 'users/user_form.html'
     form_class =  UserForm
     success_url = reverse_lazy('users:user_admin')
 
 # Delete
 class UserDeleteView(LoginRequiredMixin, DeleteView):
     model = User
     template_name = 'users/user_confirm_delete.html'
     success_url = reverse_lazy('users:user_admin')
 

在视图中我们分别使用了UserFilter, UserTableUserForm, 它们分别位于users目录下的filters.py, tables.pyforms.py,代码如下所示。它们的作用分别是定义使用哪些字段对用户进行筛选,将哪些用户字段展示在表格上以及使用哪些字段创建和更新用户。

 # users/filters.py
 import django_filters
 from django.db.models import Q
 from .models import User
 
 class UserFilter(django_filters.FilterSet):
     '''
     Filter user by username, email, is_staff, ect
     '''
     # 自定义过滤字段
     query = django_filters.CharFilter(method='my_custom_filter', label='关键词')
 
     def my_custom_filter(self, queryset, q, value):
         return queryset.filter(Q(username__icontains=value) | Q(email__icontains=value))
 
     class Meta:
         # 使用哪个模型和哪些字段过滤
         model = User
         fields = {
             'is_staff',
             'is_superuser',
             'is_active'
         }
 
 # users/tables.py
 import django_tables2 as tables
 from django.utils.html import format_html
 from django.urls import reverse
 from .models import User
 
 class UserTable(tables.Table):
     id_select = tables.CheckBoxColumn(accessor="id", orderable=False, exclude_from_export=True)
     actions = tables.Column(empty_values=(), verbose_name="操作", orderable=False, exclude_from_export=True)
 
     class Meta:
         # 使用哪个模型
         model = User
         # 表格中显示哪些字段
         fields = ['username', 'email', 'first_name', 'last_name', 'is_staff']
         # 表格中字段显示顺序
         sequence = ['id_select'] + fields + ['actions']
         # 表格模板
         template_name = "users/bs4_tables2.html"
         # 表格样式
         attrs = {"class": "table table-striped table-sm text-nowrap"}
         # 排序字段
         order_by_field = 'sort_by' # default: sort
         # page_field = 'page'
 
     # 自定义操作链接
     def render_actions(self, value, record):
         return format_html(
         '' + '编辑' + ''
         + '' + '删除' + ''
         )
 
 # users/forms.py
 from django import forms
 from .models import User
 
 class UserForm(forms.ModelForm):
     class Meta:
         # 自定义使用哪个模型和哪些字段来创建和更新用户
         model = User
         fields = ('username', 'email', 'password', 'first_name', 'last_name')
 
         widgets = {
             'password':forms.PasswordInput(),
         }

本例视图采用基于类的视图(CBV)编写,如果你对CBV还不了解,请阅读下面几篇文章。

  • Django核心基础(3): View视图详解。一旦你使用通用视图,你就会爱上她。

  • 如何使用Django通用视图的get_queryset, get_context_data和get_object等方法

  • Django实战: 使用通用类视图开发任务管理CRUD小应用(附GitHub源码)

第四步 编写模板

本项目一共使用到6个模板文件,它们位于users\templates\users目录下:

Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)_第5张图片

这里着重看下user_admin.html的代码,它继承了BS4风格的base.html, 使用了bs_form.html来显示表单和render_table命令渲染BS4风格的表格。

 {% raw %}
 {% extends 'users/base.html' %}
 {% load django_tables2 %}
 
 {% block content %}
      
             
                     
管理用户
             
             
                                                                                     
     
       
             
                 
                     
                                                   
                                                           
                     
                 
             
                 
                                                                                                                      重置                                                              
         
        {% render_table table %}  {% endblock %}{% endraw %}

本例中的base.htmlbs_form.htmlbs4_tables2.html都是高度可重用的Bootstrap 4模板,可以无需修改适用于任何项目和app。我们再看一遍展示效果吧:

Django实战:使用django-filter和django-tables2打造美观的管理后台(附图)_第6张图片

整个项目一共只有25个文件,非常值得一看和学习练手哦。

 create mode 100644 myproject/db.sqlite3
 create mode 100644 myproject/manage.py
 create mode 100644 myproject/myproject/__init__.py
 create mode 100644 myproject/myproject/asgi.py
 create mode 100644 myproject/myproject/settings.py
 create mode 100644 myproject/myproject/urls.py
 create mode 100644 myproject/myproject/wsgi.py
 create mode 100644 myproject/requirements.txt
 create mode 100644 myproject/users/__init__.py
 create mode 100644 myproject/users/admin.py
 create mode 100644 myproject/users/apps.py
 create mode 100644 myproject/users/filters.py
 create mode 100644 myproject/users/forms.py
 create mode 100644 myproject/users/migrations/__init__.py
 create mode 100644 myproject/users/models.py
 create mode 100644 myproject/users/tables.py
 create mode 100644 myproject/users/templates/users/base.html
 create mode 100644 myproject/users/templates/users/bs4_tables2.html
 create mode 100644 myproject/users/templates/users/bs_form.html
 create mode 100644 myproject/users/templates/users/user_admin.html
 create mode 100644 myproject/users/templates/users/user_confirm_delete.html
 create mode 100644 myproject/users/templates/users/user_form.html
 create mode 100644 myproject/users/tests.py
 create mode 100644 myproject/users/urls.py
 create mode 100644 myproject/users/views.py

关注微信公众号【Python Web与Django开发】,发送消息【Django后台实战】,可以获取GitHub源码地址,下载完整项目和精美的html模板, 有问题还可入群交流!

大江狗

2021.5

相关阅读

Django中间件案例由浅入深+实战

Django-filter教程详解: 从安装使用到高阶美化分页-大江狗精品

Django 3.0实战: 仿链家二手房信息查询网(附GitHub源码)

你可能感兴趣的:(django,mvvm,java,web,epoll)