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

Django:基于Formsets生成维护检查表表单的技术咨询

Hey there! Let's break down exactly how to build this maintenance checklist using Django formsets—this is a perfect use case for them. First, let's fix a tiny syntax issue in your model that'll cause headaches later: your is_compliant field is missing parentheses. Update it to is_compliant = models.BooleanField(default=False) (adding a default makes sense so new entries start unchecked).


Step 1: Define a Single Item Form

We need a form that displays the maintenance item's details (as read-only) and lets users toggle compliance status. We'll pass each Maintenance_Item instance to the form to populate the static fields.

from django import forms
from .models import MaintenanceCheckList, Maintenance_Item

class MaintenanceCheckForm(forms.ModelForm):
    # Read-only fields to display item details
    item_name = forms.CharField(label="Item Name", disabled=True)
    item_description = forms.CharField(
        label="Description", 
        disabled=True, 
        widget=forms.Textarea(attrs={'rows': 2, 'cols': 50})
    )

    class Meta:
        model = MaintenanceCheckList
        fields = ['is_compliant']

    def __init__(self, *args, **kwargs):
        # Grab the associated Maintenance_Item from kwargs
        self.maintenance_item = kwargs.pop('maintenance_item', None)
        super().__init__(*args, **kwargs)
        
        # Populate read-only fields if we have an item
        if self.maintenance_item:
            self.fields['item_name'].initial = self.maintenance_item.name
            self.fields['item_description'].initial = self.maintenance_item.name_description
        
        # Make the compliance label clearer
        self.fields['is_compliant'].label = "Mark as compliant today?"
Step 2: Create the Formset

Use Django's formset_factory to generate a set of forms—one for every existing Maintenance_Item. We'll disable extra empty forms since we only want forms for existing items.

MaintenanceCheckFormSet = forms.formset_factory(
    MaintenanceCheckForm,
    extra=0,  # No extra empty forms
    can_delete=False  # No delete functionality needed
)
Step 3: Build the View

The view will handle both rendering the formset and processing submissions. We'll fetch all maintenance items, bind each to a form, and save compliance records when the form is submitted.

from django.shortcuts import render, redirect
from datetime import date
from .forms import MaintenanceCheckFormSet
from .models import Maintenance_Item, MaintenanceCheckList

def maintenance_checklist_view(request):
    maintenance_items = Maintenance_Item.objects.all()

    if request.method == 'POST':
        formset = MaintenanceCheckFormSet(request.POST)
        if formset.is_valid():
            # Loop through forms and save compliance status
            for form, item in zip(formset, maintenance_items):
                is_compliant = form.cleaned_data['is_compliant']
                # Avoid duplicate entries for the same day
                checklist_entry, created = MaintenanceCheckList.objects.get_or_create(
                    item=item,
                    created_date__date=date.today(),
                    defaults={'is_compliant': is_compliant}
                )
                # Update existing entry if it already exists
                if not created:
                    checklist_entry.is_compliant = is_compliant
                    checklist_entry.save()
            return redirect('maintenance_checklist')  # Redirect to avoid resubmissions
    else:
        # Initialize formset with empty data, then bind each form to its item
        formset = MaintenanceCheckFormSet(initial=[{} for _ in maintenance_items])
        for form, item in zip(formset, maintenance_items):
            form.maintenance_item = item

    return render(request, 'maintenance_checklist.html', {'formset': formset})
Step 4: Render the Template

Create a template to display the formset. Don't forget to include the management_form—Django needs this to track formset data.

<!-- templates/maintenance_checklist.html -->
<form method="post">
    {% csrf_token %}
    {{ formset.management_form }}
    
    <div class="checklist-grid">
        {% for form in formset %}
            <div class="checklist-card">
                <h3>{{ form.item_name.value }}</h3>
                <p>{{ form.item_description.value }}</p>
                <div class="compliance-toggle">
                    {{ form.is_compliant }} {{ form.is_compliant.label }}
                </div>
                {{ form.hidden_fields }}
            </div>
        {% endfor %}
    </div>

    <button type="submit" class="save-btn">Save Compliance Status</button>
</form>
Pro Tip: Make It More Robust

If you're worried about form order getting messed up (e.g., if items are added/removed between page loads), add a hidden field to track the item ID in each form:

Add this to MaintenanceCheckForm:

item_id = forms.IntegerField(widget=forms.HiddenInput())

Then in the form's __init__ method:

self.fields['item_id'].initial = self.maintenance_item.id

And update the view's submission logic to fetch the item by ID instead of using zip:

for form in formset:
    if form.is_valid():
        item_id = form.cleaned_data['item_id']
        item = Maintenance_Item.objects.get(id=item_id)
        is_compliant = form.cleaned_data['is_compliant']
        # ... rest of the save logic

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 08:38:15