Django4全栈进阶之路21 项目实战(三种方式开发部门管理):方式二:CBV+Django内置类(ListView, CreateView, UpdateView, DeleteView, DetailView)

发布时间 2023-04-30 00:41:25作者: 城南城南

在 Django 中,视图(View)是处理请求并返回响应的主要机制。Django 中有许多视图类可用于处理常见的 CRUD(Create、Read、Update、Delete)操作以及其他类型的请求和响应。

以下是 Django 中最常用的五个视图类:

  1. ListView:用于显示一个对象列表的视图,通常用于显示数据库中的多条记录。
  2. CreateView:用于创建一个新对象的视图,通常用于在数据库中插入一条新的记录。
  3. UpdateView:用于更新现有对象的视图,通常用于修改数据库中的一条记录。
  4. DeleteView:用于删除一个对象的视图,通常用于从数据库中删除一条记录。
  5. DetailView:用于显示单个对象的视图,通常用于显示数据库中的一条记录。

这些视图类都是 Django 内置的类,可以从 django.views.generic 模块中导入。它们提供了一些默认的行为和模板,可以通过继承和覆盖来进行自定义。

定义了五个视图类,每个类都提供了一个默认的模板和默认的行为。在 ListViewCreateViewUpdateView 中,我们指定了要使用的模型类和要使用的表单字段。在 DeleteView 中,我们指定了成功删除对象后要重定向到的 URL。在 DetailView 中,我们只指定了要使用的模型类,因为该视图不需要表单或其他数据。

当请求被发送到这些视图之一时,Django 将自动使用默认的模板和默认的行为来处理请求,并返回相应的响应。如果需要,我们可以通过覆盖视图类的方法或指定自定义的模板来自定义视图的行为。

示例:

1、视图

class DepartmentsListView(LoginRequiredMixin, ListView):
    model = Department
    template_name = 'base/depart/departments_list.html'
    context_object_name = 'departments'
    ordering = ['name']


class DepartmentsDetailView(LoginRequiredMixin, DetailView):
    model = Department
    template_name = 'base/depart/departments_detail.html'
    context_object_name = 'department'


class DepartmentsCreateView(LoginRequiredMixin, CreateView):
    model = Department
    fields = ['name', 'parent', 'description', 'sort', 'owner', 'phone', 'email', 'status']
    template_name = 'base/depart/departments_edit.html'
    success_url = reverse_lazy('departments_list')

    def form_valid(self, form):
        form.instance.created_by = self.request.user
        form.instance.updated_by = self.request.user
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form_title'] = '新增部门'
        context['form_text'] = '新增'
        context['parent_departments'] = Department.objects.all()
        return context


class DepartmentsUpdateView(LoginRequiredMixin, UpdateView):
    model = Department
    fields = ['name', 'parent', 'description', 'sort', 'owner', 'phone', 'email', 'status']
    template_name = 'base/depart/departments_edit.html'
    success_url = reverse_lazy('departments_list')

    def form_valid(self, form):
        form.instance.updated_by = self.request.user
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form_title'] = '编辑部门'
        context['form_text'] = '保存'
        context['parent_departments'] = Department.objects.exclude(pk=self.object.pk)
        return context


class DepartmentsDeleteView(LoginRequiredMixin, DeleteView):
    model = Department
    template_name = 'base/depart/departments_delete.html'
    success_url = reverse_lazy('department_list')

 

2、路由

from django.urls import path

from .views import DepartmentsListView, DepartmentsCreateView, DepartmentsUpdateView, DepartmentsDeleteView, \
    DepartmentsDetailView

# 路由
urlpatterns = [
    # CBV模式from ListView, CreateView, UpdateView, DeleteView, DetailView
    path('departments/', DepartmentsListView.as_view(), name='departments_list'),
    path('departments/<int:pk>/', DepartmentsDetailView.as_view(), name='departments_detail'),
    path('departments/add/', DepartmentsCreateView.as_view(), name='departments_add'),
    path('departments/<int:pk>/update/', DepartmentsUpdateView.as_view(), name="departments_edit"),
    path('departments/delete/<int:pk>/', DepartmentsDeleteView.as_view(), name="departments_delete"),
]

3、前端模板

departments_list.html
{% extends 'base.html' %}

{% block content %}
    <div style="margin-top: 16px;">
        <a href="{% url 'departments_add' %}" class="btn btn-primary mb-3">添加部门</a>
    </div>
    <div class="card mt-3">
        <div class="card-header">部门列表</div>
        <div class="card-body">
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>部门名称</th>
                    <th>父级部门</th>
                    <th>显示排序</th>
                    <th>负责人</th>
                    <th>联系电话</th>
                    <th>邮箱</th>
                    <th>部门状态</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {% for department in departments %}
                    <tr>
                        <td>{{ department.id }}</td>
                        <td>{{ department.name }}</td>
                        <td>{{ department.parent }}</td>
                        <td>{{ department.sort }}</td>
                        <td>{{ department.owner }}</td>
                        <td>{{ department.phone }}</td>
                        <td>{{ department.email }}</td>
                        <td>{{ department.status }}</td>
                        <td>
                            <a class="btn btn-primary btn-xs"
                               href="{% url 'departments_detail' department.id %}">详情</a>
                            <a class="btn btn-primary btn-xs" href="{% url 'departments_edit' department.id %}">编辑</a>
                            <a class="btn btn-danger btn-xs"
                               href="{% url 'departments_delete' department.id %}">删除</a>
                        </td>
                    </tr>
                {% empty %}
                    <tr>
                        <td colspan="9" style="text-align: center;">No departments yet.</td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{% endblock %}

 

 

departments_edit.html
{% extends 'base.html' %}
{% load widget_tweaks %}

{% block content %}
    <div class="container py-4">
        <div class="card">
            <div class="card-header">
                <h3 class="card-title">{{ form_title }}</h3>
            </div>
            <div class="card-body">
                <form method="post">
                    {% csrf_token %}
                    {#                方法一#}
                    {#                {{ form.as_p }}#}
                    {#                方法二#}
                    <div class="form-group">
                        <label for="{{ form.name.id_for_label }}">部门名称:</label>
                        {{ form.name|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.parent.id_for_label }}">父级部门:</label>
                        {{ form.parent|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.description.id_for_label }}">部门介绍:</label>
                        {{ form.description|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.sort.id_for_label }}">显示排序:</label>
                        {{ form.sort|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.owner.id_for_label }}">负责人:</label>
                        {{ form.owner|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.phone.id_for_label }}">联系电话:</label>
                        {{ form.phone|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.email.id_for_label }}">邮箱:</label>
                        {{ form.email|attr:"class:form-control" }}
                    </div>
                    <div class="form-group">
                        <label for="{{ form.status.id_for_label }}">部门状态:</label>
                        {{ form.status|attr:"class:form-control" }}
                    </div>
                    <button type="submit" class="btn btn-primary">{{ form_text }}</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

 


department_detail.html
{% extends 'base.html' %}

{% block content %}
<div class="container py-4">
  <div class="card">
    <div class="card-header">
      <h3 class="card-title">{{ department.name }}</h3>
    </div>
    <div class="card-body">
      <ul class="list-group">
        <li class="list-group-item"><strong>部门名称:</strong>{{ department.name }}</li>
        <li class="list-group-item"><strong>上级部门:</strong>{% if department.parent %}<a href="{% url 'department_detail' department.parent.id %}">{{ department.parent.name }}</a>{% else %}-{% endif %}</li>
        <li class="list-group-item"><strong>创建账号:</strong>{{ department.created_by.username }}</li>
        <li class="list-group-item"><strong>创建时间:</strong>{{ department.created_at }}</li>
        <li class="list-group-item"><strong>修改账号:</strong>{{ department.updated_by.username }}</li>
        <li class="list-group-item"><strong>最后修改时间:</strong>{{ department.updated_at }}</li>
      </ul>
    </div>
  </div>
</div>
{% endblock %}

 


departments_delete.html
{% extends 'base.html' %}

{% block content %}
    <div class="container py-4">
        <div class="card">
            <div class="card-header">
                <h3 class="card-title">删除部门</h3>
            </div>
            <div class="card-body">
                <p>您确定要删除部门 "{{ department.name }}" 吗?</p>
                <form method="post">
                    {% csrf_token %}
                    <button type="submit" class="btn btn-primary">删除</button>
                    <a href="{% url 'departments_list' %}?success=true" class="btn btn-secondary">取消</a>

                </form>
            </div>
        </div>
    </div>
{% endblock %}