整体步骤概览
- 创建项目和应用
- 设计模型(Model) - 定义设备的数据结构
- 配置用户认证(Auth) - 使用 Django 自带的强大用户系统
- 创建视图(View) - 处理业务逻辑:登录、列表、增删改查
- 编写模板(Template) - 设计前端页面
- 配置路由(URL) - 将 URL 映射到视图
- 运行测试
第一步:创建项目和应用
# 1. 在合适的位置创建项目目录并进入
mkdir my_device_manager
cd my_device_manager
# 2. 创建虚拟环境(推荐)
python -m venv venv
# 3. 激活虚拟环境
# On Windows:
venv\Scripts\activate
# On macOS/Linux:
source venv/bin/activate
# 4. 安装 Django
pip install django
# 5. 创建Django项目,名为 `my_site`
django-admin startproject my_site .
# 6. 创建一个名为 `devices` 的应用来处理设备相关的功能
python manage.py startapp devices
# 7. 将新应用 `devices` 和 Django 自带的 `auth` 应用添加到设置中
# 编辑 my_site/settings.py
编辑 my_site/settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth', # 用户认证系统
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'devices', # 添加你的应用
]
同时,在文件末尾配置数据库(默认使用 SQLite,无需修改即可用)和静态文件。
第二步:设计设备模型 (Model)
编辑 devices/models.py:
from django.db import models
from django.contrib.auth.models import User
class Device(models.Model):
# 设备类型选择
TYPE_CHOICES = (
('router', '路由器'),
('switch', '交换机'),
('server', '服务器'),
('pc', '个人电脑'),
('other', '其他'),
)
name = models.CharField(max_length=100, verbose_name="设备名称")
ip_address = models.GenericIPAddressField(verbose_name="IP地址")
type = models.CharField(max_length=20, choices=TYPE_CHOICES, default='other', verbose_name="设备类型")
description = models.TextField(blank=True, null=True, verbose_name="设备描述")
# 添加创建时间和更新时间
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
# 将设备与用户关联(一个用户拥有多个设备)
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='devices', verbose_name="所属用户")
def __str__(self):
return f"{self.name} ({self.ip_address})"
class Meta:
verbose_name = "设备"
verbose_name_plural = "设备"
创建数据库表:
# 生成迁移文件
python manage.py makemigrations
# 执行迁移,在数据库中创建表
python manage.py migrate
第三步:创建处理逻辑的视图 (View)
编辑 devices/views.py:
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Device
from .forms import DeviceForm # 我们稍后会创建这个表单
def user_login(request):
"""用户登录视图"""
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
messages.success(request, f'欢迎回来,{username}!')
return redirect('device_list')
else:
messages.error(request, '用户名或密码错误!')
return render(request, 'registration/login.html')
@login_required
def user_logout(request):
"""用户登出视图"""
logout(request)
messages.info(request, '您已成功登出。')
return redirect('user_login')
@login_required
def device_list(request):
"""设备列表视图,只显示当前用户的设备"""
devices = Device.objects.filter(owner=request.user)
return render(request, 'devices/device_list.html', {'devices': devices})
@login_required
def device_create(request):
"""创建设备视图"""
if request.method == 'POST':
form = DeviceForm(request.POST)
if form.is_valid():
new_device = form.save(commit=False)
new_device.owner = request.user # 自动设置设备所有者為当前用户
new_device.save()
messages.success(request, f'设备 {new_device.name} 创建成功!')
return redirect('device_list')
else:
form = DeviceForm()
return render(request, 'devices/device_form.html', {'form': form, 'title': '添加新设备'})
@login_required
def device_update(request, pk):
"""更新设备视图"""
device = get_object_or_404(Device, pk=pk, owner=request.user) # 确保用户只能修改自己的设备
if request.method == 'POST':
form = DeviceForm(request.POST, instance=device)
if form.is_valid():
form.save()
messages.success(request, f'设备 {device.name} 更新成功!')
return redirect('device_list')
else:
form = DeviceForm(instance=device)
return render(request, 'devices/device_form.html', {'form': form, 'title': '编辑设备'})
@login_required
def device_delete(request, pk):
"""删除设备视图"""
device = get_object_or_404(Device, pk=pk, owner=request.user)
if request.method == 'POST':
device_name = device.name
device.delete()
messages.success(request, f'设备 {device_name} 已删除。')
return redirect('device_list')
return render(request, 'devices/device_confirm_delete.html', {'device': device})
第四步:创建表单 (Form)
Django 的表单可以简化 HTML 表单的创建和验证。
创建 devices/forms.py:
from django import forms
from .models import Device
class DeviceForm(forms.ModelForm):
class Meta:
model = Device
fields = ['name', 'ip_address', 'type', 'description']
widgets = {
'description': forms.Textarea(attrs={'rows': 4}),
}
labels = {
'name': '设备名称',
'ip_address': 'IP地址',
'type': '设备类型',
'description': '描述',
}
第五步:设计前端页面 (Templates)
创建以下模板文件目录结构和内容。
- 基础模板 devices/templates/base.html:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>设备管理系统</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="{% url 'device_list' %}">设备管理</a> <div class="navbar-nav ms-auto"> {% if user.is_authenticated %} <span class="navbar-text me-3">你好,{{ user.username }}</span> <form method="post" action="{% url 'user_logout' %}"> {% csrf_token %} <button type="submit" class="btn btn-outline-light btn-sm">登出</button> </form> {% else %} <a class="nav-link" href="{% url 'user_login' %}">登录</a> {% endif %} </div> </div> </nav> <div class="container mt-4"> <!-- 消息提示 --> {% if messages %} {% for message in messages %} <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert"> {{ message }} <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> {% endfor %} {% endif %} <!-- 主要内容 --> {% block content %} {% endblock %} </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script> </body> </html>
- 登录页面 devices/templates/registration/login.html:
{% extends 'base.html' %} {% block content %} <div class="row justify-content-center"> <div class="col-md-6"> <h2 class="mb-4">用户登录</h2> <form method="post"> {% csrf_token %} <div class="mb-3"> <label for="username" class="form-label">用户名</label> <input type="text" class="form-control" id="username" name="username" required> </div> <div class="mb-3"> <label for="password" class="form-label">密码</label> <input type="password" class="form-control" id="password" name="password" required> </div> <button type="submit" class="btn btn-primary">登录</button> </form> </div> </div> {% endblock %}
- 设备列表页 devices/templates/devices/device_list.html:
{% extends 'base.html' %} {% block content %} <div class="d-flex justify-content-between align-items-center mb-4"> <h2>我的设备列表</h2> <a href="{% url 'device_create' %}" class="btn btn-success">+ 添加新设备</a> </div> {% if devices %} <div class="table-responsive"> <table class="table table-striped table-hover"> <thead class="table-dark"> <tr> <th>设备名称</th> <th>IP地址</th> <th>类型</th> <th>创建时间</th> <th>操作</th> </tr> </thead> <tbody> {% for device in devices %} <tr> <td>{{ device.name }}</td> <td>{{ device.ip_address }}</td> <td>{{ device.get_type_display }}</td> <td>{{ device.created_at|date:"Y-m-d H:i" }}</td> <td> <a href="{% url 'device_update' device.pk %}" class="btn btn-sm btn-outline-primary">编辑</a> <a href="{% url 'device_delete' device.pk %}" class="btn btn-sm btn-outline-danger">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> {% else %} <div class="alert alert-info">您还没有添加任何设备。 <a href="{% url 'device_create' %}">点击添加</a></div> {% endif %} {% endblock %}
- 设备表单页(创建/编辑共用) devices/templates/devices/device_form.html:
{% extends 'base.html' %} {% block content %} <h2 class="mb-4">{{ title }}</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="btn btn-primary">保存</button> <a href="{% url 'device_list' %}" class="btn btn-secondary">取消</a> </form> {% endblock %}
- 删除确认页 devices/templates/devices/device_confirm_delete.html:
{% extends 'base.html' %} {% block content %} <h2 class="mb-4">确认删除</h2> <p>你确定要删除设备 <strong>{{ device.name }}</strong> ({{ device.ip_address }}) 吗?此操作不可逆。</p> <form method="post"> {% csrf_token %} <button type="submit" class="btn btn-danger">是的,删除</button> <a href="{% url 'device_list' %}" class="btn btn-secondary">取消</a> </form> {% endblock %}
第六步:配置路由 (URL)
- 应用级路由 devices/urls.py (需要创建这个文件):
from django.urls import path from . import views app_name = 'devices' urlpatterns = [ path('', views.device_list, name='device_list'), path('login/', views.user_login, name='user_login'), path('logout/', views.user_logout, name='user_logout'), path('new/', views.device_create, name='device_create'), path('<int:pk>/edit/', views.device_update, name='device_update'), path('<int:pk>/delete/', views.device_delete, name='device_delete'), ]
- 项目级路由 my_site/urls.py:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('devices.urls')), # 将根路径指向 devices 应用的路由 ]
第七步:运行测试
# 创建超级用户,用于登录后台和管理用户(可选,但推荐)
python manage.py createsuperuser
# 按照提示输入用户名、邮箱和密码
# 启动开发服务器
python manage.py runserver
- 打开浏览器访问 http://127.0.0.1:8000
- 你应该会被重定向到登录页面。你可以使用刚刚创建的超级用户登录。
- 登录成功后,你会看到设备列表页(初始为空)。
- 点击“添加新设备”进行测试。
功能清单验证:
· ✅ 用户登录/登出
· ✅ 设备列表显示(只显示当前用户的)
· ✅ 创建设备
· ✅ 编辑设备
· ✅ 删除设备(有确认提示)
这个系统已经具备了核心功能。你可以在此基础上继续扩展,比如添加更复杂的设备字段、实现搜索过滤、添加分页功能等。Django Admin 后台 (/admin) 也可以直接管理所有设备和用户数据。