You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django多模型CRUD优化:无需为每个操作编写视图与模板?

不用重复写!Django多模型CRUD的简便实现方式

当然不需要为每个模型的每个CRUD操作都单独写视图函数和模板,有几种高效的方案可以大幅减少重复代码:

1. 用Django内置的通用类视图(Class-Based Views)

Django自带了一系列封装好的通用视图,专门用来处理CRUD场景,你只需要指定模型和少量配置,就能快速实现功能,甚至可以复用模板。

示例代码:

在views.py中,为不同模型复用通用视图:

from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import Employee, Department  # 假设还有Department模型

# 提取通用配置作为基类
class BaseCRUD:
    success_url = reverse_lazy('home')  # 操作成功后的跳转地址,可按需调整
    fields = '__all__'  # 使用模型所有字段生成表单

# Employee模型的CRUD
class EmployeeList(BaseCRUD, ListView):
    model = Employee
    template_name = 'generic/list.html'  # 通用列表模板

class EmployeeCreate(BaseCRUD, CreateView):
    model = Employee
    template_name = 'generic/form.html'  # 通用表单模板

class EmployeeUpdate(BaseCRUD, UpdateView):
    model = Employee
    template_name = 'generic/form.html'

class EmployeeDelete(BaseCRUD, DeleteView):
    model = Employee
    template_name = 'generic/delete.html'

# Department模型直接复用基类,只需修改model
class DepartmentList(BaseCRUD, ListView):
    model = Department
    template_name = 'generic/list.html'

class DepartmentCreate(BaseCRUD, CreateView):
    model = Department
    template_name = 'generic/form.html'

通用模板示例:

generic/list.html(适配所有模型的列表页面):

<h1>{{ model._meta.verbose_name_plural|title }}</h1>
<ul>
{% for item in object_list %}
    <li>{{ item }} 
        <a href="{% url 'update' model_name=model._meta.model_name pk=item.pk %}">编辑</a>
        <a href="{% url 'delete' model_name=model._meta.model_name pk=item.pk %}">删除</a>
    </li>
{% endfor %}
</ul>
<a href="{% url 'create' model_name=model._meta.model_name %}">添加新{{ model._meta.verbose_name }}</a>

generic/form.html(适配创建/更新操作):

<h1>{% if object %}编辑{{ object }}{% else %}添加新{{ model._meta.verbose_name }}{% endif %}</h1>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">保存</button>
</form>
<a href="{% url 'list' model_name=model._meta.model_name %}">返回列表</a>

2. 自定义通用CRUD视图(单视图处理所有模型)

如果想更极致地复用,你可以写一个动态视图,根据URL传入的模型名称,自动处理对应的CRUD操作,完全不用为每个模型写视图。

示例代码:

from django.shortcuts import render, redirect
from django.forms import modelform_factory
from .models import Employee, Department

# 映射模型名称到模型类,避免不安全的动态导入
MODEL_MAP = {
    'employee': Employee,
    'department': Department,
}

def generic_crud(request, model_name, pk=None):
    model = MODEL_MAP.get(model_name)
    if not model:
        return redirect('home')
    
    # 动态生成对应模型的表单
    FormClass = modelform_factory(model, fields='__all__')
    instance = model.objects.get(pk=pk) if pk else None

    if request.method == 'POST':
        form = FormClass(request.POST, instance=instance)
        if form.is_valid():
            form.save()
            return redirect('generic_list', model_name=model_name)
    else:
        form = FormClass(instance=instance)
    
    context = {
        'form': form,
        'model': model,
        'object': instance
    }
    return render(request, 'generic/form.html', context)

def generic_list(request, model_name):
    model = MODEL_MAP.get(model_name)
    if not model:
        return redirect('home')
    context = {
        'object_list': model.objects.all(),
        'model': model
    }
    return render(request, 'generic/list.html', context)

def generic_delete(request, model_name, pk):
    model = MODEL_MAP.get(model_name)
    if not model:
        return redirect('home')
    instance = model.objects.get(pk=pk)
    if request.method == 'POST':
        instance.delete()
        return redirect('generic_list', model_name=model_name)
    return render(request, 'generic/delete.html', {'object': instance, 'model': model})

对应的URL配置:

from django.urls import path
from . import views

urlpatterns = [
    path('<str:model_name>/', views.generic_list, name='generic_list'),
    path('<str:model_name>/create/', views.generic_crud, name='generic_create'),
    path('<str:model_name>/<int:pk>/', views.generic_crud, name='generic_update'),
    path('<str:model_name>/<int:pk>/delete/', views.generic_delete, name='generic_delete'),
]

3. 直接用Django Admin(零代码CRUD)

如果只是需要后台管理的CRUD功能,Django Admin是最省事的选择——只需要在admin.py中注册模型,就能直接使用完整的CRUD界面,完全不用写视图和模板:

from django.contrib import admin
from .models import Employee, Department

admin.site.register(Employee)
admin.site.register(Department)

启动项目后访问/admin,就能对所有注册的模型进行CRUD操作。

总结

不管是用内置通用视图、自定义动态视图,还是直接用Admin,都能避免重复编写大量的视图和模板代码。其中自定义动态视图可以做到一个视图处理所有模型的CRUD,配合通用模板,20个模型也只需要一套核心代码就能搞定。

内容的提问来源于stack exchange,提问作者PeroML

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:41:04