Add battery inline editing for UPS host

This commit is contained in:
xiaji
2026-04-30 10:34:07 +08:00
parent c7fa0a8dd0
commit cea28e5b62
3 changed files with 187 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
from django import forms
from django.forms import inlineformset_factory
from .models import UPSHost, Battery
class BatteryForm(forms.ModelForm):
class Meta:
model = Battery
fields = ['brand', 'model', 'weight', 'quantity', 'location', 'install_date', 'last_maintenance_date']
labels = {
'brand': '电池品牌',
'model': '电池型号',
'weight': '重量(kg)',
'quantity': '数量',
'location': '存放位置',
'install_date': '安装日期',
'last_maintenance_date': '上次维保时间',
}
widgets = {
'brand': forms.TextInput(attrs={'class': 'form-control form-control-sm'}),
'model': forms.TextInput(attrs={'class': 'form-control form-control-sm'}),
'weight': forms.NumberInput(attrs={'class': 'form-control form-control-sm', 'step': '0.1'}),
'quantity': forms.NumberInput(attrs={'class': 'form-control form-control-sm', 'min': '1'}),
'location': forms.TextInput(attrs={'class': 'form-control form-control-sm'}),
}
BatteryFormSet = inlineformset_factory(
UPSHost,
Battery,
form=BatteryForm,
extra=0,
can_delete=True,
fields=['brand', 'model', 'weight', 'quantity', 'location', 'install_date', 'last_maintenance_date']
)

View File

@@ -116,6 +116,114 @@
</div>
</div>
{% if object and battery_formset %}
<hr class="my-5">
<div class="card">
<div class="card-header bg-success text-white">
<h5 class="mb-0">下挂电池管理</h5>
</div>
<div class="card-body">
{{ battery_formset.management_form }}
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>电池品牌</th>
<th>电池型号</th>
<th>重量(kg)</th>
<th>数量</th>
<th>存放位置</th>
<th>安装日期</th>
<th>上次维保</th>
<th>删除</th>
</tr>
</thead>
<tbody>
{% for battery_form in battery_formset %}
<tr>
<td>
{{ battery_form.id }}
{{ battery_form.brand }}
{% if battery_form.brand.errors %}
{% for error in battery_form.brand.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
{{ battery_form.model }}
{% if battery_form.model.errors %}
{% for error in battery_form.model.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
{{ battery_form.weight }}
{% if battery_form.weight.errors %}
{% for error in battery_form.weight.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
{{ battery_form.quantity }}
{% if battery_form.quantity.errors %}
{% for error in battery_form.quantity.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
{{ battery_form.location }}
{% if battery_form.location.errors %}
{% for error in battery_form.location.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
<input type="text"
class="form-control form-control-sm datepicker-battery"
id="{{ battery_form.install_date.id_for_label }}"
name="{{ battery_form.install_date.name }}"
value="{{ battery_form.install_date.value|date:'Y-m-d' }}"
placeholder="选择日期">
{% if battery_form.install_date.errors %}
{% for error in battery_form.install_date.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
<input type="text"
class="form-control form-control-sm datepicker-battery"
id="{{ battery_form.last_maintenance_date.id_for_label }}"
name="{{ battery_form.last_maintenance_date.name }}"
value="{{ battery_form.last_maintenance_date.value|date:'Y-m-d' }}"
placeholder="选择日期">
{% if battery_form.last_maintenance_date.errors %}
{% for error in battery_form.last_maintenance_date.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</td>
<td>
{{ battery_form.DELETE }}
</td>
</tr>
{% empty %}
<tr>
<td colspan="8" class="text-center text-muted">暂未下挂电池</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<div class="mt-5 d-flex justify-content-end gap-3">
<a href="{% url 'ups_list' %}" class="btn btn-secondary px-6">
<i class="fas fa-arrow-left mr-2"></i>取消
@@ -143,6 +251,16 @@
minDate: '1900-01-01',
maxDate: new Date()
});
flatpickr('.datepicker-battery', {
dateFormat: 'Y-m-d',
locale: 'zh',
allowInput: true,
todayButton: true,
clearButton: true,
minDate: '1900-01-01',
maxDate: new Date()
});
});
</script>
@@ -164,6 +282,17 @@
border-radius: 8px;
box-shadow: 0 10px 40px rgba(0,0,0,0.15);
}
.table-responsive {
overflow-x: auto;
}
.form-control-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
}
.table th {
font-size: 0.875rem;
white-space: nowrap;
}
</style>
{% endblock %}

View File

@@ -1,7 +1,9 @@
from django.shortcuts import render, redirect
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.contrib import messages
from .models import UPSHost, Battery, Contact, Supplier, MaintenanceRecord
from .forms import BatteryFormSet
class DashboardView(ListView):
@@ -106,6 +108,27 @@ class UPSHostUpdateView(UpdateView):
template_name = 'ups_manager/ups_form.html'
fields = ['brand', 'model', 'ip_address', 'quantity', 'location', 'last_maintenance_date', 'contact']
success_url = reverse_lazy('ups_list')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
context['battery_formset'] = BatteryFormSet(self.request.POST, instance=self.object)
else:
context['battery_formset'] = BatteryFormSet(instance=self.object)
return context
def form_valid(self, form):
context = self.get_context_data()
battery_formset = context['battery_formset']
if battery_formset.is_valid():
self.object = form.save()
battery_formset.instance = self.object
battery_formset.save()
messages.success(self.request, 'UPS主机和电池信息已更新')
return redirect(self.success_url)
else:
return self.form_invalid(form)
class UPSHostDeleteView(DeleteView):