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

Django中如何同时展示数据库表与表单,及单条数据保存方案?

需求

在页面中实现一个可展示数据库所有字段的表单,支持修改字段内容并保存至数据库,作为简易的数据库表编辑器。

现有实现代码

HTML代码

<tr>
    <td>{{ form.name }}</td>
    <td>{{ form.token }}</td>
    <td><button class="btn btn-lg btn-success w-100">Add</button></td>
</tr>

models.py

from django.db import models

# Create your models here.
class TrafficSources(models.Model):
    name = models.CharField('名称', max_length=250)
    token = models.CharField('令牌', max_length=250)

    def __str__(self):
        return self.name

forms.py

from .models import TrafficSources
from django.forms import ModelForm, TextInput

class TrafficSourcesForm(ModelForm):
    class Meta:
        model = TrafficSources
        fields = ['name', 'token']
        widgets = {
            'name': TextInput(attrs={
                'class': 'form-control'
            }),
            'token': TextInput(attrs={
                'class': 'form-control'
            })
        }

views.py

import requests
from django.shortcuts import render
from .models import TrafficSources
from .forms import TrafficSourcesForm

def settings(request):
    ts = TrafficSources.objects.all()
    form = TrafficSourcesForm()
    url = 'API请求地址'
    
    # 获取propeller对应的token
    ts_token = TrafficSources.objects.filter(name='propeller').first()
    token = ts_token.token if ts_token else ''
    headers = {'Authorization': 'Bearer ' + token}
    res = requests.get(url, headers=headers) if token else None
    
    return render(request, 'mainpage/dashboard.html', {
        'ts': ts, 
        'js': res.text if res else '', 
        'hd': headers, 
        'form': form
    })

技术问询

  1. 目前可单独在HTML页面展示数据库表或空白表单,但无法在同一位置同时实现两者的展示,该如何解决?
  2. 若需实现每个字段单独保存至数据库的功能,是否需要为每行数据单独设置表单,还是仅通过一个页面表单即可实现?

效果参考图:
效果参考图


解决方案

问题1:同时展示数据库数据与表单

要在同一页面同时呈现现有数据和可编辑/新增的表单,需分两种场景处理:

  • 遍历数据库查询集ts,把每条数据渲染成带输入框的编辑行;
  • 保留空白表单行,用于添加新记录。

修改后的核心HTML代码:

<table class="table">
    <thead>
        <tr>
            <th>名称</th>
            <th>令牌</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        <!-- 遍历现有数据生成编辑行 -->
        {% for item in ts %}
        <tr>
            <form method="post" action="{% url 'update_traffic_source' item.id %}">
                {% csrf_token %}
                <td><input type="text" name="name" class="form-control" value="{{ item.name }}"></td>
                <td><input type="text" name="token" class="form-control" value="{{ item.token }}"></td>
                <td><button type="submit" class="btn btn-primary w-100">保存</button></td>
            </form>
        </tr>
        {% endfor %}
        <!-- 新增数据的表单行 -->
        <tr>
            <form method="post" action="{% url 'add_traffic_source' %}">
                {% csrf_token %}
                <td>{{ form.name }}</td>
                <td>{{ form.token }}</td>
                <td><button type="submit" class="btn btn-success w-100">添加</button></td>
            </form>
        </tr>
    </tbody>
</table>

问题2:字段单独保存的实现方式

必须为每行数据单独设置表单,因为每条数据对应不同的数据库记录,单独表单可以通过记录ID精准定位修改对象,避免提交时数据混淆。

配套新增视图函数(views.py):

from django.shortcuts import redirect, get_object_or_404

# 新增记录
def add_traffic_source(request):
    if request.method == 'POST':
        form = TrafficSourcesForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('settings')
    return redirect('settings')

# 更新记录
def update_traffic_source(request, pk):
    item = get_object_or_404(TrafficSources, pk=pk)
    if request.method == 'POST':
        item.name = request.POST.get('name')
        item.token = request.POST.get('token')
        item.save()
        return redirect('settings')
    return redirect('settings')

补充路由配置(urls.py):

from django.urls import path
from . import views

urlpatterns = [
    path('settings/', views.settings, name='settings'),
    path('settings/add/', views.add_traffic_source, name='add_traffic_source'),
    path('settings/update/<int:pk>/', views.update_traffic_source, name='update_traffic_source'),
]

注:原forms.py中的placeholder需求,编辑行直接用value="{{ item.name }}"填充现有数据即可;新增行可在widgets里添加placeholder="输入名称"这类固定提示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:35:23