实现点击表格行加载数据至表单并支持编辑回写的Django方案问询
Hey there! Looks like you want to turn your existing table into an inline editable interface where clicking a row populates a form next to it for updates—great idea, that's a common and user-friendly pattern. Let's walk through how to adjust your Django code to make this happen.
First, Set Up the Model Form
You'll need a ModelForm for your ArkiObject_1 model to handle editing. Create or update your forms.py with this:
from django import forms from .models import ArkiObject_1 class ArkiObjectEditForm(forms.ModelForm): class Meta: model = ArkiObject_1 fields = ['city', 'nameobject', 'typeobject', 'budget', 'podryadchik']
Update the Main View to Handle Editing
Modify your table view to handle both displaying the table and processing edit submissions. We'll add logic to save updates when the form is submitted, and pass the edit form to the template:
from django.shortcuts import get_object_or_404, redirect from .forms import ArkiObjectEditForm def table(request): context = {} # Keep your existing filter logic book_filter = BookFilter(request.GET, queryset=ArkiObject_1.objects.all()) table_2 = book_filter.qs # Handle edit form submission if request.method == 'POST' and 'edit_save' in request.POST: obj_pk = request.POST.get('object_pk') object_to_edit = get_object_or_404(ArkiObject_1, pk=obj_pk) edit_form = ArkiObjectEditForm(request.POST, instance=object_to_edit) if edit_form.is_valid(): edit_form.save() return redirect('table') # Refresh to show updated data else: # Empty form for initial load edit_form = ArkiObjectEditForm() # Pass context variables as before, plus the edit form context['form'] = book_filter.form context['edit_form'] = edit_form table = pd.DataFrame.from_records(table_2.values("city", "nameobject", "typeobject", "budget", "podryadchik")) context['table'] = table context['books'] = table_2 return render(request, "table.html", context)
Adjust the Template for Inline Editing
Update your table.html to:
- Add the edit form next to your filter form
- Make table rows clickable with data attributes holding row values
- Add JavaScript to populate the form when a row is clicked
Here's the modified template snippet:
<div style="display: flex; gap: 20px;"> <!-- Filter Form --> <div> <h4>Фильтр</h4> <form method="GET" action="{% url 'table' %}"> {{ form.as_p }} <input type="submit" value="Фильтровать" class="button" /> </form> </div> <!-- Edit Form --> <div> <h4>Редактировать запись</h4> <form method="POST" action="{% url 'table' %}"> {% csrf_token %} {{ edit_form.as_p }} <input type="hidden" name="object_pk" id="object_pk"> <input type="submit" name="edit_save" value="Сохранить изменения" class="button" /> </form> </div> </div> <br/> <!-- Clickable Table --> <div> <table style="font-family: Arial, Helvetica, sans-serif; font-size: small; border-collapse: collapse;"> <thead> <tr> {% for col in table.columns %} <th style="border: 1px solid #ddd; padding: 8px;">{{ col }}</th> {% endfor %} </tr> </thead> <tbody> {% for book in books %} <tr class="editable-row" data-pk="{{ book.pk }}" data-city="{{ book.city }}" data-nameobject="{{ book.nameobject }}" data-typeobject="{{ book.typeobject }}" data-budget="{{ book.budget }}" data-podryadchik="{{ book.podryadchik }}" style="cursor: pointer; border: 1px solid #ddd;"> {% for cell in book.values_list "city", "nameobject", "typeobject", "budget", "podryadchik" %} <td style="text-align: center; padding: 8px;">{{ cell }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </div> <!-- JavaScript to Populate Form --> <script> document.addEventListener('DOMContentLoaded', function() { const rows = document.querySelectorAll('.editable-row'); rows.forEach(row => { row.addEventListener('click', function() { // Pull data from row's data attributes const pk = this.dataset.pk; const city = this.dataset.city; const nameobject = this.dataset.nameobject; const typeobject = this.dataset.typeobject; const budget = this.dataset.budget; const podryadchik = this.dataset.podryadchik; // Populate the edit form fields document.getElementById('id_city').value = city; document.getElementById('id_nameobject').value = nameobject; document.getElementById('id_typeobject').value = typeobject; document.getElementById('id_budget').value = budget; document.getElementById('id_podryadchik').value = podryadchik; document.getElementById('object_pk').value = pk; }); }); }); </script>
Key Notes:
- Clickable Rows: We added a
editable-rowclass and data attributes to each table row to store the object's ID and field values. When clicked, JavaScript reads these attributes and fills the form. - Edit Form Handling: The view checks for a POST request with
edit_saveto distinguish between filter submissions (GET) and edit saves (POST). We useinstance=object_to_editto tell the form to update an existing record instead of creating a new one. - User Experience: The form is placed next to the filter form using flexbox for a clean layout, and rows have a pointer cursor to indicate they're clickable.
Alternative for Complex Data:
If your fields have special characters or you want to avoid storing data in HTML attributes, you could use an AJAX call to fetch the object details when a row is clicked. For example, add a URL endpoint that returns the object as JSON, then use fetch() in JavaScript to populate the form.
This setup should give you exactly what you want: click a row, edit its data in the adjacent form, save it back to the database, and see the updated table immediately.
内容来源于stack exchange

