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://www.pswp.cn/bicheng/96786.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96786.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96786.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

補 json的作用

&#xff1a;“我開車直接擰鑰匙就能走&#xff0c;為什么還要看儀表盤和用中控臺&#xff1f;”直接點擊“運行”&#xff0c;就像是汽車的自動駕駛模式。它能幫你開起來&#xff0c;但你不知道它走的是哪條路&#xff0c;油門踩多深。使用 launch.json 配置&#xff0c;就像是…

apache詳細講解(apache介紹+apache配置實驗+apache實現https網站)

1.apache HTTP server介紹httpd項目地址:https://httpd.apache.org/ 在Apache2中有三種工作模式&#xff0c;使用者可以根據不同的業務場景來進行選擇(1)prefork模式prefork模式是一種老而穩的模式:一個主進程管理者多個子進程&#xff0c;每個子進程單獨處理用戶請求&#xf…

jajajajajajajava

線程1 線程概念進程:進程指正在內存中運行的程序。進程具有一定的獨立性。線程:線程是進程中的一個執行單元。負責當前進程中程序的執行。一個進程中至少有一個線程。如果一個進程中有多個線程&#xff0c;稱之為多線程程序。java中的線程采用的是搶占式調度&#xff0c;如果線…

虛擬機CentOS里JDK的安裝與環境配置

---本文以JDK17為例---步驟 1&#xff1a;進入/tmp臨時目錄# 進入臨時目錄 cd /tmp步驟 2&#xff1a;下載 Java 17 安裝包wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.tar.gz步驟 3&am…

mybatis-plus多租戶兼容多字段租戶標識

默認租戶插件處理器的缺陷 在springboot工程中引入mybatis-plus的租戶插件TenantLineInnerInterceptor&#xff0c;能簡化我們的數據隔離操作&#xff0c;例如各類含租戶用戶登錄權限的rest接口中&#xff0c;不需要再根據登錄用戶-set租戶條件-觸發查詢&#xff0c;租戶插件能…

HBase高級特性(布隆過濾器和協處理器)、列族設計、rowkey設計以及熱點問題處理

在闡述HBase高級特性和熱點問題處理前&#xff0c;首先回顧一下HBase的特點&#xff1a;分布式、列存儲、支持實時讀寫、存儲的數據類型都是字節數組byte[]&#xff0c;主要用來處理結構化和半結構化數據&#xff0c;底層數據存儲基于hdfs。 同時&#xff0c;HBase和傳統數據庫…

redis sentinel 與 clauster 的區別

Redis Sentinel(哨兵)和Redis Cluster(集群)是Redis提供的兩種不同的高可用和擴展性解決方案,它們的設計目標和適用場景有顯著區別: 1. 核心功能與目標 Redis Sentinel 主要解決主從架構的高可用問題,實現自動故障轉移 監控主從節點狀態,當主節點故障時自動將從節點提…

MySQL數據庫中快速導入大數據sql

1.PwerShell命令頁面導入全表數據庫 -P3310 指定數據庫端口號Get-Content "本地sql文件目錄" | .\mysql -u root -p -P 33102.PwerShell命令頁面導入單表到數據庫 -P3310 指定數據庫端口號Get-Content "本地sql文件目錄" | .\mysql -u root -p -P 3310 數…

消息類型proto的編寫和生成

消息類型proto的編寫和生成 代碼如下&#xff1a; syntax"proto3"; package xypmq;enum ExchangeType {UNKNOWNTYPE0;DIRECT1;FANOUT2;TOPIC3; };enum DeliveryMode {UNKNOWNMODE0;UNDURABLE1;DURABLE2; };message BasicProperties {string id1;DeliveryMode deliver…

Vuetify:構建優雅Vue應用的Material Design組件庫

Vuetify是一個基于Material Design設計規范的Vue.js UI組件庫&#xff0c;它提供了80多個精心設計的組件&#xff0c;幫助開發者快速構建美觀且功能豐富的企業級應用。核心特性1. 完整的Material Design實現// 所有組件遵循Material Design規范 <v-btn color"primary&q…

SpringBoot 注解深剖:@RequestParam 與 @RequestBody 的終極對決,90% 的開發者都踩過這些坑!

在 SpringBoot 開發中&#xff0c;處理 HTTP 請求參數是我們每天都要面對的工作。而RequestParam和RequestBody這兩個注解&#xff0c;就像是我們手中的兩把利劍&#xff0c;既能高效解決問題&#xff0c;用不好也可能 "誤傷" 自己。作為一名資深 Java 開發者&#x…

【Docker】P2 Docker環境構建準備:MacOS 與 Linux

目錄操作系統與 Docker 的兼容性分析Docker 技術本質MacOS 環境下的 Docker 構建1. 安裝前準備2. Docker Desktop安裝3. 鏡像加速配置高級操作&#xff1a;文件共享配置Linux 環境下的 Docker 構建卸載歷史版本配置軟件源Docker 核心組件安裝系統服務配置鏡像加速器配置應用配置…

OpenCV 發票識別全流程:透視變換與輪廓檢測詳解

目錄 前言 一、核心技術原理&#xff1a;透視變換與輪廓檢測 1. 透視變換&#xff1a;讓傾斜發票 “正過來” &#xff08;1&#xff09;什么是透視變換&#xff1f; &#xff08;2&#xff09;透視變換的 5 個關鍵步驟 2. 輪廓檢測&#xff1a;精準定位發票區域 &#x…

并發:使用volatile和不可變性實現線程安全

《Java并發編程實戰》中的VolatileCachedFactorizer展示了如何使用volatile和不可變性來實現線程安全。解決了簡單緩存實現中可能出現的線程安全問題&#xff0c;同時避免了全量同步帶來的性能開銷。 場景背景 假設有一個服務&#xff08;如因數分解服務&#xff09;&#xff0…

Linux x86 stability和coredump

1 POSIX pthread_create原理 1&#xff09;fork()、pthread_create()、vfork()對應的系統調用分別是sys_fork()、sys_clone()、sys_vfork()&#xff0c;它們在內核中都是通過do_fork()實現的。 2&#xff09;系統中所有的進程都組織在init_task.tasks鏈表下面&#xff0c;每個進…

【PyTorch】多對象分割

對象分割任務的目標是找到圖像中目標對象的邊界。實際應用例如自動駕駛汽車和醫學成像分析。這里將使用PyTorch開發一個深度學習模型來完成多對象分割任務。多對象分割的主要目標是自動勾勒出圖像中多個目標對象的邊界。 對象的邊界通常由與圖像大小相同的分割掩碼定義&#xf…

RabbitMQ---面試題

總結我們所學內容&#xff0c;這里推薦博客進行復習 RabbitMQ---面試題_rabbitmq常問面試題-CSDN博客

MasterGo自動布局(Auto Layout)

自動布局是用來表示 子元素與子元素之間互相影響的一種排版方式,是一種響應式布局技術。一般是將所有元素設計完成后再使用自動布局進行設置。 自動布局就是響應式布局,就是在不同尺寸的手機上寬度不同都應該怎么展示。 一般頁面的一級元素使用約束進行相對定位,二級元素及里…

還在重啟應用改 Topic?Spring Boot 動態 Kafka 消費的“終極形態”

場景描述&#xff1a; 你的一個微服務正在穩定地消費 Kafka 的 order_topic。現在&#xff0c;上游系統為了做業務隔離&#xff0c;新增加了一個 order_topic_vip&#xff0c;并開始向其中投遞 VIP 用戶的訂單。你需要在不重啟、不發布新版本的情況下&#xff0c;讓你現有的消費…

使用vllm部署neo4j的text2cypher-gemma-2-9b-it-finetuned-2024v1模型

使用vllm部署neo4j的text2cypher-gemma-2-9b-it-finetuned-2024v1模型 系統環境準備 由于使用的基于 nvcr.io/nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04 的 workbench,需要進行以下準備(其他系統環境可忽略) ldconfig -p | grep libcudnn 找到 libcudnn 的so庫,然…