当前位置: 首页 > news >正文

Django ModelForm:快速构建数据库表单

Django 中的 forms.ModelForm —— 它是 Django 表单系统和 ORM 的一个“桥梁”,能帮助你快速基于 数据库模型(Model) 自动生成表单,极大减少重复代码。


1. 什么是 ModelForm

  • 普通 Form (forms.Form):完全手写字段,和数据库模型没有直接关系。
  • ModelForm (forms.ModelForm):根据 Django ORM 的 Model 自动生成表单字段,避免重复定义字段。

换句话说,ModelForm = Form + Model 映射
你只需要指定关联的模型 model,Django 会自动:

  1. 根据模型字段生成对应的表单字段;
  2. 自动处理数据校验(包括数据库字段约束,如 max_lengthunique);
  3. 提供 save() 方法,可以直接保存到数据库。

2. 基本用法

模型定义

# models.py
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=50)published_date = models.DateField()price = models.DecimalField(max_digits=6, decimal_places=2)def __str__(self):return self.title

ModelForm 定义

# forms.py
from django import forms
from .models import Bookclass BookForm(forms.ModelForm):class Meta:model = Bookfields = '__all__'   # 或 ['title', 'author']

视图中使用

# views.py
from django.shortcuts import render, redirect
from .forms import BookFormdef create_book(request):if request.method == "POST":form = BookForm(request.POST)if form.is_valid():       # 自动根据模型字段校验form.save()           # 直接保存到数据库return redirect('book_list')else:form = BookForm()return render(request, 'book_form.html', {'form': form})

模板中渲染

<form method="post">{% csrf_token %}{{ form.as_p }}   <!-- 自动渲染为 <p> 包裹的表单控件 --><button type="submit">保存</button>
</form>

3. ModelForm 的关键点

3.1 Meta 类配置

ModelForm 必须包含一个 Meta 内部类,用来定义表单和模型的关系。

常用属性:

  • model:指定关联的模型
  • fields:指定要包含的字段(推荐用列表,不要总用 __all__
  • exclude:排除某些字段
  • widgets:指定表单控件样式(比如 HTML input)
  • labels:自定义字段的标签
  • help_texts:字段提示文字
  • error_messages:自定义错误提示

示例:

class BookForm(forms.ModelForm):class Meta:model = Bookfields = ['title', 'author', 'price']   # 只要部分字段labels = {'title': '书名','author': '作者',}help_texts = {'price': '请输入价格(单位:元)',}error_messages = {'title': {'max_length': '书名太长了!',},}widgets = {'published_date': forms.SelectDateWidget(years=range(2000, 2030)),}

4. 表单数据的保存

4.1 新增

form = BookForm(request.POST)
if form.is_valid():book = form.save()   # 直接保存到数据库

4.2 不立即保存

有时候需要在保存前修改对象,可以用 commit=False

book = form.save(commit=False)
book.price = book.price * 0.9   # 打折
book.save()

4.3 更新已有对象

book = Book.objects.get(pk=1)
form = BookForm(request.POST, instance=book)  # 绑定已有对象
if form.is_valid():form.save()  # 会执行 update 而不是 insert

5. 表单校验

5.1 自动校验

  • 来自模型字段的限制(max_lengthuniqueblank 等)
  • 自动映射到表单校验规则

5.2 自定义校验

可以通过重写 clean_<field>()clean()

方法名中的<field>必须和表单字段名一致;

class BookForm(forms.ModelForm):class Meta:model = Bookfields = '__all__'def clean_price(self):price = self.cleaned_data['price']if price <= 0:raise forms.ValidationError("价格必须大于0!")return pricedef clean(self):cleaned_data = super().clean()title = cleaned_data.get('title')author = cleaned_data.get('author')if title and author and "Django" not in title and author == "某某":raise forms.ValidationError("某某只能写 Django 相关的书!")return cleaned_data

调用顺序:

  • 表单调用了 is_valid(),从而触发了 full_clean() → clean_fields() → clean_<field>()

6. ModelForm 的高级用法

6.1 内联表单(Inline Formset)

Django 提供了 inlineformset_factory,可以在一个表单中编辑主表和子表。
常用于:一个 Author 对应多个 Book 的场景。

from django.forms import inlineformset_factory
BookFormSet = inlineformset_factory(Author, Book, fields=['title', 'price'])

6.2 ModelFormmodelform_factory

如果表单逻辑简单,可以用 modelform_factory 快速生成:

from django.forms import modelform_factory
BookForm = modelform_factory(Book, fields=['title', 'author'])

7. Form vs ModelForm 对比

特点FormModelForm
字段定义手动写每个字段自动从 Model 生成
数据校验需手动写自动结合 Model 的字段规则
保存到数据库需手动处理模型对象保存直接用 save()
使用场景与数据库无关的表单与模型强关联的 CRUD 表单

8. 使用场景总结

✅ 适合:

  • 表单与数据库模型字段高度一致的场景(如后台管理系统、标准 CRUD 表单)
  • 希望快速生成表单,减少重复代码

⚠️ 不适合:

  • 表单和模型差别很大(例如前端提交的数据字段和数据库存储结构完全不一样)
  • 需要复杂的自定义逻辑时,建议继承 forms.Form

文章转载自:

http://92fJigmG.cykqb.cn
http://bIYoG1UQ.cykqb.cn
http://Vfu8ARVz.cykqb.cn
http://d0DwXVAH.cykqb.cn
http://xCE8sVHJ.cykqb.cn
http://U5Qe5iK9.cykqb.cn
http://4dLZIvrH.cykqb.cn
http://ZsIPmQdP.cykqb.cn
http://5yhfKa8i.cykqb.cn
http://fOVttXVn.cykqb.cn
http://MD2uCmC9.cykqb.cn
http://njkqA8Mh.cykqb.cn
http://6Yzger12.cykqb.cn
http://QCasCgVO.cykqb.cn
http://SbgHmJ95.cykqb.cn
http://w680diia.cykqb.cn
http://QJ03VA6G.cykqb.cn
http://IrWLzQVt.cykqb.cn
http://5FYyMSOv.cykqb.cn
http://V2CsWjiA.cykqb.cn
http://9CZ7Takz.cykqb.cn
http://stplxxmV.cykqb.cn
http://Pj9exaB4.cykqb.cn
http://4UhMPAaL.cykqb.cn
http://wHt2Wr2S.cykqb.cn
http://0iL7bmzO.cykqb.cn
http://pu8R0oFM.cykqb.cn
http://FeF1SjDK.cykqb.cn
http://Qg4y2qFL.cykqb.cn
http://MeoeAmeF.cykqb.cn
http://www.dtcms.com/a/375498.html

相关文章:

  • 【迭代】:本地高性能c++对话系统e2e_voice
  • SSE与Websocket、Http的关系
  • 蓓韵安禧DHA展现温和配方的藻油与鱼油营养特色
  • 基于UNet的视网膜血管分割系统
  • python函数和面向对象
  • 嵌入式 - ARM(3)从基础调用到 C / 汇编互调
  • 07MySQL存储引擎与索引优化
  • 面向OS bug的TypeState分析
  • 【文献笔记】Task allocation for multi-AUV system: A review
  • 小红书批量作图软件推荐运营大管家小红书批量作图工具
  • ArrayList详解与实际应用
  • 德意志飞机公司与DLR合作完成D328 UpLift演示机地面振动测试
  • MongoDB 备份与恢复终极指南:mongodump 和 mongorestore 深度实战
  • ctfshow - web - 命令执行漏洞总结(二)
  • 基于STM32的GPS北斗定位系统
  • 2025年大陆12寸晶圆厂一览
  • VMware Workstation Pro 安装教程
  • Java Spring @Retention三种保留策略
  • 低代码平台的核心组件与功能解析:红迅低代码平台实战探秘
  • linux sudo权限
  • PM2 管理后端(设置项目自启动)
  • 中国香港服务器中常提到的双向/全程CN2是什么意思?
  • DCS+PLC协同优化:基于MQTT的分布式控制系统能效提升案例
  • Backend
  • 分布式专题——6 Redis缓存设计与性能优化
  • 《智能网联汽车交通仿真软件可信度评估》团标启动会圆满举办
  • 无人机云台电压类型及测量方法
  • 光伏无人机3D设计——高效出方案的快速设计方式!
  • K8s角色权限管理全解析
  • Postgresql 发送数据到Splunk