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

如何在Django中使用HTML表单实现后端数据输入?

解决Django表单数据提交的完整方案

作为Django新手,我来一步步带你搞定从HTML表单到后端数据存储的流程——先从你的表单调整入手,再依次编写模型、表单、视图和路由。

第一步:修复HTML表单的核心问题

你的表单里大部分输入元素都缺少name属性,这是Django后端能获取到数据的关键!另外单选按钮、复选框的配置也需要调整,修改后的表单代码如下:

<form method='POST' id="new_post" action="/posts/new/"> 
    {% csrf_token %} 
    <div class="form-group col-md-6"> 
        <label>Title</label><br> 
        <input type="text" name="title" class="form-control" id="inputTitle" placeholder="Enter title"> 
    </div> 
    <div class="form-group col-md-12"> 
        <label>Situation Description</label><br> 
        <textarea name="situation_desc" rows="4" cols="70" class="form-control" placeholder="Enter the situation description"></textarea> 
    </div> 
    <div class="form-group col-md-12"> 
        <label>Outcome Description</label><br> 
        <textarea name="outcome_desc" rows="4" cols="70" class="form-control" placeholder="Enter the outcome description"></textarea> 
    </div> 
    <div class="form-group col-md-4"> 
        <label>Outcome Type</label><br> 
        <select name="outcome_type" id="inputO_type" class="form-control"> 
            <option value="positive">Positive</option> 
            <option value="neutral">Neutral</option> 
            <option value="negative">Negative</option> 
        </select> 
    </div> 
    <br> 
    <div class="form-group col-md-4"> 
        <div class="multiselect"> 
            <div class="selectBox" onclick="showCheckboxes()"> 
                <select></select>
                <option>reviewed?</option>
                <div class="overSelect"></div> 
            </div> 
            <div id="checkboxes"> 
                <label for="one"> 
                    <input type="checkbox" name="reviewed_types" id="one" value="commissioning" />Commissioning</label> 
                <label for="two"> 
                    <input type="checkbox" name="reviewed_types" id="two" value="construction" />Construction</label> 
            </div> 
        </div>
    </div> 
    <div class="form-row"> 
        <br> 
        <div class="form-group col-md-4"> 
            <label>Tags</label><br> 
            <select name="tags" id="inputTag" class="form-control" multiple> 
                <option value="algorithms">Algorithms</option> 
                <option value="architecture">Architecture</option> 
                <option value="automobile">Automobile</option> 
                <option>...</option> 
            </select> 
        </div> 
        <div class="form-row"> 
            <div class="form-group col-md-4"> 
                <div> 
                    <input type="checkbox" name="custom_tag_check" id="FormStuff"> 
                    <label for="FormStuff">Can't find your tag?</label> 
                    <div class="reveal-if-active"> 
                        <label for="which-tag">Please fill in your desired tag below</label><br> 
                        <input type="text" id="which-tag" name="custom_tag" class="require-if-active" data-require-pair="#choice-tags-typetags"> 
                    </div> 
                </div> 
            </div> 
        </div> 
        <br> 
        <div class="form-group col-md-4"> 
            <label>Does this warrant a process improvement action?</label> 
            <div class="form-check"> 
                <input type="radio" name="improvement_action" class="form-check-input" value="yes"> 
                <label>Yes</label> 
            </div> 
            <div class="form-check"> 
                <input type="radio" name="improvement_action" class="form-check-input" value="no"> 
                <label>No</label> 
            </div> 
        </div> 
    </div>
    <!-- 补充提交按钮 -->
    <button type="submit" class="btn btn-primary">Submit Post</button>
</form>

主要修改点:

  • 给所有需要提交的元素添加name属性(比如title、situation_desc),后端靠这个识别数据
  • 给下拉选框、单选/复选框添加明确的value值,避免后端拿到空值
  • 多选标签的select加上multiple属性,支持多选
  • 修复了嵌套<form>的无效结构
  • 添加了提交按钮

第二步:编写models.py(定义数据模型)

先定义存储帖子数据的模型,对应你的表单字段:

# posts/models.py
from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    # 关联发布帖子的用户
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    situation_desc = models.TextField()
    outcome_desc = models.TextField()
    # 结果类型选项
    OUTCOME_CHOICES = [
        ('positive', 'Positive'),
        ('neutral', 'Neutral'),
        ('negative', 'Negative'),
    ]
    outcome_type = models.CharField(max_length=10, choices=OUTCOME_CHOICES)
    # 审核类型:用逗号分隔存储多个选项(后期可优化为ManyToMany)
    reviewed_types = models.CharField(max_length=100, blank=True)
    # 标签:用逗号分隔存储(后期可优化为独立Tag模型)
    tags = models.CharField(max_length=200)
    # 是否需要流程改进
    IMPROVEMENT_CHOICES = [
        ('yes', 'Yes'),
        ('no', 'No'),
    ]
    improvement_action = models.CharField(max_length=3, choices=IMPROVEMENT_CHOICES)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

如果后期需要更灵活的标签管理(比如重复使用、搜索),可以单独创建Tag模型,再用ManyToManyField关联到Post。


第三步:编写forms.py(表单验证)

用Django的ModelForm可以自动处理数据验证,比原生表单更规范:

# posts/forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    # 自定义多选复选框的渲染
    reviewed_types = forms.MultipleChoiceField(
        choices=[
            ('commissioning', 'Commissioning'),
            ('construction', 'Construction'),
        ],
        widget=forms.CheckboxSelectMultiple,
        required=False
    )
    # 自定义多选标签的渲染
    tags = forms.MultipleChoiceField(
        choices=[
            ('algorithms', 'Algorithms'),
            ('architecture', 'Architecture'),
            ('automobile', 'Automobile'),
            # 可在这里添加更多预设标签
        ],
        widget=forms.SelectMultiple,
        required=False
    )

    class Meta:
        model = Post
        fields = ['title', 'situation_desc', 'outcome_desc', 'outcome_type', 'reviewed_types', 'tags', 'improvement_action']

这个表单类直接关联Post模型,自动生成对应字段,同时自定义了多选控件的渲染方式。


第四步:编写views.py(处理表单提交)

视图负责接收表单数据、验证并保存到数据库:

# posts/views.py
from django.shortcuts import render, redirect
from .forms import PostForm
from django.contrib.auth.decorators import login_required

@login_required  # 限制只有登录用户才能发帖
def create_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            # 先不保存,关联当前登录用户
            post = form.save(commit=False)
            post.author = request.user
            # 处理多选审核类型:转成逗号分隔的字符串
            post.reviewed_types = ','.join(form.cleaned_data['reviewed_types'])
            # 处理标签:如果用户填了自定义标签,追加进去
            tags = form.cleaned_data['tags']
            custom_tag = request.POST.get('custom_tag')
            if custom_tag and request.POST.get('custom_tag_check'):
                tags.append(custom_tag)
            post.tags = ','.join(tags)
            # 保存帖子到数据库
            post.save()
            # 跳转到首页或帖子详情页(需在urls.py定义对应路由)
            return redirect('home')
    else:
        # GET请求时显示空表单
        form = PostForm()
    return render(request, 'posts/create_post.html', {'form': form})

关键逻辑说明:

  • 用@login_required确保用户登录才能发帖
  • 验证表单数据有效性,避免非法数据存入
  • 关联当前用户作为帖子作者
  • 处理多选字段的格式转换(列表转字符串)
  • 支持用户自定义标签的追加

第五步:编写urls.py(配置路由)

先在项目根urls.py中引入posts应用的路由:

# 项目根urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('posts/', include('posts.urls')),
    # 其他路由...
]

然后在posts应用中新建urls.py:

# posts/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('new/', views.create_post, name='create_post'),
    # 可添加帖子列表、详情页等路由
]

这样表单的action="/posts/new/"就能正确指向create_post视图了。


额外提示

  1. 如果你想简化HTML编写,可以在模板中直接用{{ form.as_p }},Django会自动渲染所有表单字段,更高效不易出错。
  2. 后期可将reviewed_types和tags改为ManyToManyField,关联独立模型,更利于数据查询和管理。
  3. 写完模型后记得运行python manage.py makemigrations和python manage.py migrate创建数据库表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:32:28