- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章php中关于普通表单多文件上传的处理方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
然而有些情况只需要传递几个文件,而且文件体积并不太大,这种情况下使用组件则有点牛刀杀鸡的感觉,通过html自带的<input type="file">表单就可以实现需要的功能,关键在于后台接收程序的处理。 php处理上传做的很方便,上传文件的信息通过服务器自动处理到$_FILES数组中,开发者只需要使用的内置处理函数简单操作就可以啦。ASP开发者则没有这么幸运,官方并没有提供直接的处理方法,需要开发者自己设计,这时就需要开发者了解IIS对enctype="multipart/form-data"表单的处理方式,IIS把enctype="multipart/form-data"表单提交的数据存储成二进制数据,以二进制格式返回给开发者,开发者则需要通过LenB、MidB的字节处理函数来分析获取的上传内容,客户端发送的具体表单数据格式,可以了解下HTTP RFC1867协议传输格式方面的知识。 下面是我处理多个文件上传的方法,包括php和asp两个版本。 php:WEBSITE_DIRROOT代表网站根目录: 。
复制代码代码如下
<?php /* * class: 文件上传类 * author: 51JS.COM-ZMM * date: 2011.1.20 * email: 304924248@qq.com * blog: http://www.cnblogs.com/cnzmm/ */ class Upload { public $up_ext=array(), $up_max=5210, $up_dir; private $up_name, $up_rename=true, $up_num=0, $up_files=array(), $up_ret=array(); function __construct($name, $ext=array(), $rename=true) { if (!empty($name)) { $this->up_name = $name; !empty($ext) && $this->up_ext = $ext; $this->up_rename = $rename; $this->up_dir = WEBSITE_DIRROOT. $GLOBALS['cfg_upload_path']; $this->InitUpload(); } else { exit('upload文件域名称为空,初始化失败!'); } } private function InitUpload() { if (is_array($_FILES[$this->up_name])) { $up_arr = count($_FILES[$this->up_name]); $up_all = count($_FILES[$this->up_name], 1); $up_cnt = ($up_all - $up_arr) / $up_arr; for ($i = 0; $i < $up_cnt; $i ++) { if ($_FILES[$this->up_name]['error'][$i] != 4) { $this->up_files[] = array( 'tmp_name' => $_FILES[$this->up_name]['tmp_name'][$i], 'name' => $_FILES[$this->up_name]['name'][$i], 'type' => $_FILES[$this->up_name]['type'][$i], 'size' => $_FILES[$this->up_name]['size'][$i], 'error' => $_FILES[$this->up_name]['error'][$i] ); } } $this->up_num = count($this->up_files); } else { if (isset($_FILES[$this->up_name])) { $this->up_files = array( 'tmp_name' => $_FILES[$this->up_name]['tmp_name'], 'name' => $_FILES[$this->up_name]['name'], 'type' => $_FILES[$this->up_name]['type'], 'size' => $_FILES[$this->up_name]['size'], 'error' => $_FILES[$this->up_name]['error'] ); $this->up_num = 1; } else { exit('没找找到需要upload的文件!'); } } $this->ChkUpload(); } private function ChkUpload() { if (empty($this->up_ext)) { $up_mime = array('image/wbmp', 'image/bmp', 'image/gif', 'image/pjpeg', 'image/x-png'); foreach ($this->up_files as $up_file) { $up_allw = false; foreach ($up_mime as $mime) { if ($up_file['type'] == $mime) { $up_allw = true; break; } } !$up_allw && exit('不允许上传'.$up_file['type'].'格式的文件!'); if ($up_file['size'] / 1024 > $this->up_max) { exit('不允许上传大于 '.$this->up_max.'K 的文件!'); } } } else { foreach ($this->up_files as $up_file) { $up_ext = end(explode('.', $up_file['name'])); $up_allw = false; foreach ($this->up_ext as $ext) { if ($up_ext == $ext) { $up_allw = true; break; } } !$up_allw && exit('不允许上传.'.$up_ext.'格式的文件!'); if ($up_file['size'] / 1024 > $this->up_max) { exit('不允许上传大于 '.$this->up_max.'K 的文件!'); } } } $this->Uploading(); } private function Uploading() { if (IO::DIRCreate($this->up_dir)) { if (chmod($this->up_dir, 0777)) { if (!empty($this->up_files)) { foreach ($this->up_files as $up_file) { if (is_uploaded_file($up_file['tmp_name'])) { $file_name = $up_file['name']; if ($this->up_rename) { $file_ext = end(explode('.', $file_name)); $file_rnd = substr(md5(uniqid()), mt_rand(0, 26), 6); $file_name = date('ymdHis').'_'.$file_rnd.'.'.$file_ext; } $file_name = $this->up_dir.'/'.$file_name; if (move_uploaded_file($up_file['tmp_name'], $file_name)) { $this->up_ret[] = str_replace(WEBSITE_DIRROOT, '', $file_name); } else { exit('文件上传失败!'); } } } } } else { exit('未开启写入权限!'); } } else { exit('上传目录创建失败!'); } } public function GetUpload() { return empty($this->up_ret) ? false : $this->up_ret; } function __destruct() {} } ?> 。
asp: 。
复制代码代码如下
<% Class MultiUpload REM PUBLIC-VARIANT Public Form, IsFinished Private bVbCrlf, bSeparate, fPassed, formData, fileType, fileSize, folderPath, _ fRename, fIMGOnly, itemCount, chunkSize, bTime, sErrors, sAuthor, sVersion Private itemStart(), itemLength(), dataStart(), dataLength(), itemName(), itemData(), extenArr(), httpArr() REM CLASS-INITIALIZE Private Sub Class_Initialize Call InitVariant Server.ScriptTimeOut = 1800 Set Form = Server.CreateObject("Scripting.Dictionary") sAuthor = "51JS.COM-ZMM" sVersion = "MultiUpload Class 3.0" End Sub REM CLASS-ATTRIBUTES Public Property Let AllowType(byVal sType) Dim regEx Set regEx = New RegExp regEx.Pattern = "^(\w+\|)*\w+$" regEx.Global = False regEx.IgnoreCase = True If regEx.Test(sType) Then fileType = "|" & Ucase(sType) & "|" Set regEx = Nothing End Property Public Property Let MaxSize(byVal sSize) If IsNumeric(sSize) Then fileSize = CDbl(FormatNumber(CCur(sSize), 2)) End Property Public Property Let SaveFolder(byVal sFolder) folderPath = sFolder End Property Public Property Let CommonPassed(byVal bCheck) fPassed = bCheck End Property Public Property Let FileRenamed(byVal bRename) fRename = bRename End Property Public Property Let FileIsAllImg(byVal bOnly) fIMGOnly = bOnly End Property Public Property Get SaveFolder SaveFolder = folderPath End Property Public Property Get FileRenamed FileRenamed = fRename End Property Public Property Get FileIsAllImg FileIsAllImg = fIMGOnly End Property Public Property Get ErrMessage ErrMessage = sErrors End Property Public Property Get ClsAuthor ClsAuthor = sAuthor End Property Public Property Get ClsVersion ClsVersion = sVersion End Property REM CLASS-METHODS Private Function InitVariant IsFinished = False bVbCrlf = StrToByte(vbCrlf & vbCrlf) bSeparate = StrToByte(String(29, "-")) fPassed = False fileType = "*" fileSize = "*" fRename = True fIMGOnly = True itemCount = 0 chunkSize = 1024 * 128 bTime = Now sErrors = "" End Function Public Function GetUploadData Dim curRead : curRead = 0 Dim dataLen : dataLen = Request.TotalBytes Dim appName : appName = "PROGRESS" & IPToNum(GetClientIPAddr) Dim streamTmp Set streamTmp = Server.CreateObject("ADODB.Stream") streamTmp.Type = 1 streamTmp.Open Do While curRead < dataLen Dim partLen : partLen = chunkSize If partLen + curRead > dataLen Then partLen = dataLen - curRead streamTmp.Write Request.BinaryRead(partLen) curRead = curRead + partLen LetProgress appName, Array(curRead, dataLen, DateDiff("s", bTime, Now), folderPath) Loop streamTmp.Position = 0 formData = streamTmp.Read(dataLen) streamTmp.Close Set streamTmp = Nothing Call ItemPosition End Function Private Function LetProgress(byVal sName, byVal vArr) Application.Value(sName) = Join(vArr, "|") End Function Private Function DelProgress Application.Contents.Remove("PROGRESS" & IPToNum(GetClientIPAddr)) End Function Private Function ItemPosition Dim iStart, iLength : iStart = 1 Do Until InStrB(iStart, formData, bSeparate) = 0 iStart = InStrB(iStart, formData, bSeparate) + LenB(bSeparate) + 14 iLength = InStrB(iStart, formData, bSeparate) - iStart - 2 If Abs(iStart + 2 - LenB(formData)) > 2 Then ReDim Preserve itemStart(itemCount) ReDim Preserve itemLength(itemCount) itemStart(itemCount) = iStart itemLength(itemCount) = iLength itemCount = itemCount + 1 End If Loop Call FillItemValue End Function Private Function FillItemValue Dim dataPart, bInfor Dim iStart : iStart = 1 Dim iCount : iCount = 0 Dim iCheck : iCheck = StrToByte("filename") For i = 0 To itemCount - 1 ReDim Preserve itemName(iCount) ReDim Preserve itemData(iCount) ReDim Preserve extenArr(iCount) ReDim Preserve httpArr(iCount) ReDim Preserve dataStart(iCount) ReDim Preserve dataLength(iCount) dataPart = MidB(formData, itemStart(i), itemLength(i)) iStart = InStrB(1, dataPart, ChrB(34)) + 1 iLength = InStrB(iStart, dataPart, ChrB(34)) - iStart itemName(iCount) = GetItemName(MidB(dataPart, iStart, iLength)) iStart = InStrB(1, dataPart, bVBCrlf) + 4 iLength = LenB(dataPart) - iStart + 1 If InStrB(1, dataPart, iCheck) > 0 Then bInfor = MidB(dataPart, 1, iStart - 5) extenArr(iCount) = FileExtenName(bInfor) httpArr(iCount) = GetHttpContent(bInfor) If IsNothing(extenArr(iCount)) Then itemData(iCount) = "" dataStart(iCount) = "" dataLength(iCount) = "" Else If Mid(folderPath, Len(folderPath) - 1) = "/" Then If fRename Then itemData(iCount) = folderPath & GetRandomName(6) & extenArr(iCount) Else itemData(iCount) = folderPath & GetClientName(bInfor) & extenArr(iCount) End If Else If fRename Then itemData(iCount) = folderPath & "/" & GetRandomName(6) & extenArr(iCount) Else itemData(iCount) = folderPath & "/" & GetClientName(bInfor) & extenArr(iCount) End If End If dataStart(iCount) = itemStart(i) + iStart - 2 dataLength(iCount) = iLength End If Else extenArr(iCount) = "" httpArr(iCount) = "" itemData(iCount) = ByteToStr(MidB(dataPart, iStart, iLength)) dataStart(iCount) = "" dataLength(iCount) = "" End If iCount = iCount + 1 Next Call ItemToColl End Function Private Function GetItemName(byVal bName) GetItemName = ByteToStr(bName) End Function Private Function ItemToColl For i = 0 To itemCount - 1 If Not Form.Exists(itemName(i)) Then Form.Add itemName(i), itemData(i) End If Next End Function Private Function FileExtenName(byVal bInfor) Dim pContent, regEx pContent = GetClientPath(bInfor) If IsNothing(pContent) Then FileExtenName = "" Else Set regEx = New RegExp regEx.Pattern = "^.+(\.[^\.]+)$" regEx.Global = False regEx.IgnoreCase = True FileExtenName = regEx.Replace(pContent, "$1") Set regEx = Nothing End If End Function Private Function GetHttpContent(byVal bInfor) Dim sInfor, regEx sInfor = ByteToStr(bInfor) Set regEx = New RegExp regEx.Pattern = "^[\S\s]+Content-Type:([\S\s]+)$" regEx.Global = False regEx.IgnoreCase = True GetHttpContent = Trim(regEx.Replace(sInfor, "$1")) Set regEx = Nothing End Function Private Function GetRandomName(byVal sLen) Dim regEx, sTemp, arrFields, n : n = 0 Set regEx = New RegExp regEx.Pattern = "[^\d]+" regEx.Global = True regEx.IgnoreCase = True sTemp = regEx.Replace(Now, "") & "-" Set regEx = Nothing arrFields = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", _ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", _ "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", _ "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", _ "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", _ "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", _ "Y", "Z") Randomize Do While n < sLen sTemp = sTemp & CStr(arrFields(61 * Rnd)) n = n + 1 Loop GetRandomName = sTemp End Function Private Function GetClientName(byVal bInfor) Dim pContent, regEx pContent = GetClientPath(bInfor) If IsNothing(pContent) Then GetClientName = "" Else Set regEx = New RegExp regEx.Pattern = "^.*\\([^\.]*)[^\\]+$" regEx.Global = False regEx.IgnoreCase = True GetClientName = regEx.Replace(pContent, "$1") Set regEx = Nothing End If End Function Private Function GetClientPath(byVal bInfor) Dim sInfor, pStart, pLength, pContent sInfor = ByteToStr(bInfor) pStart = InStr(1, sInfor, "filename=" & Chr(34)) + 10 pLength = InStr(pStart, sInfor, Chr(34)) - pStart pContent = Mid(sInfor, pStart, pLength) GetClientPath = pContent End Function Public Function SaveUploadFile Dim isValidate Dim filePath, oStreamGet, oStreamPut isValidate = fPassed And CheckFile If isValidate Then For i = 0 To itemCount - 1 If Not IsNothing(dataStart(i)) And Not IsNothing(dataLength(i)) Then If dataLength(i) = 0 Then itemData(i) = "" Else filePath = Server.MapPath(itemData(i)) If CreateFolder("|", ParentFolder(filePath)) Then Set oStreamGet = Server.CreateObject("ADODB.Stream") oStreamGet.Type = 1 oStreamGet.Mode = 3 oStreamGet.Open oStreamGet.Write formData oStreamGet.Position = dataStart(i) Set oStreamPut = Server.CreateObject("ADODB.Stream") oStreamPut.Type = 1 oStreamPut.Mode = 3 oStreamPut.Open oStreamPut.Write oStreamGet.Read(dataLength(i)) oStreamPut.SaveToFile filePath, 2 oStreamGet.Close Set oStreamGet = Nothing oStreamPut.Close Set oStreamPut = Nothing End If End If End If Next IsFinished = True Else IsFinished = False End If End Function Private Function CheckFile Dim oBoolean : oBoolean = True CheckFile = oBoolean And CheckType And CheckSize End Function Private Function CheckType Dim oBoolean : oBoolean = True If fileType = "*" Then oBoolean = oBoolean And True Else For i = 0 To itemCount - 1 If Not IsNothing(extenArr(i)) Then If InStr(1, fileType, "|" & Ucase(Mid(extenArr(i), 2)) & "|") > 0 Then If fIMGOnly Then Dim sAllow : sAllow = "|GIF|PJPEG|X-PNG|BMP|" Dim aCheck : aCheck = Split(UCase(httpArr(i)), "/") Dim iCheck : iCheck = "|" & aCheck(Ubound(aCheck)) & "|" If InStr(1, sAllow, iCheck, 1) > 0 Then oBoolean = oBoolean And True Else sErrors = sErrors & "表单 [ " & itemName(i) & " ] 的文件格式错误!\n" & _ "支持的格式为:" & Replace(Mid(fileType, 2, Len(fileType) - 1), "|", " ") & "\n\n" oBoolean = oBoolean And False End If Else oBoolean = oBoolean And True End If Else sErrors = sErrors & "表单 [ " & itemName(i) & " ] 的文件格式错误!\n" & _ "支持的格式为:" & Replace(Mid(fileType, 2, Len(fileType) - 1), "|", " ") & "\n\n" oBoolean = oBoolean And False End If End If Next End If CheckType = oBoolean End Function Private Function CheckSize Dim oBoolean : oBoolean = True If fileSize = "*" Then oBoolean = oBoolean And True Else For i = 0 To itemCount - 1 If Not IsNothing(dataLength(i)) Then Dim tmpSize : tmpSize = CDbl(FormatNumber(CCur(dataLength(i)) / 1024, 2)) If tmpSize <= fileSize Then oBoolean = oBoolean And True Else sErrors = sErrors & "表单 [ " & itemName(i) & " ] 的文件大小 (" & tmpSize & " KB) 超出范围!\n" & _ "支持大小范围:<= " & fileSize & " KB\n\n" oBoolean = oBoolean And False End If End If Next End If CheckSize = oBoolean End Function Private Function CreateFolder(byVal sLine, byVal sPath) Dim oFso Set oFso = Server.CreateObject("Scripting.FileSystemObject") If Not oFso.FolderExists(sPath) Then Dim regEx Set regEx = New RegExp regEx.Pattern = "^(.*)\\([^\\]*)$" regEx.Global = False regEx.IgnoreCase = True sLine = sLine & regEx.Replace(sPath, "$2") & "|" sPath = regEx.Replace(sPath, "$1") If CreateFolder(sLine, sPath) Then CreateFolder = True Set regEx = Nothing Else If sLine = "|" Then CreateFolder = True Else Dim sTemp : sTemp = Mid(sLine, 2, Len(sLine) - 2) If InStrRev(sTemp, "|") = 0 Then sLine = "|" sPath = sPath & "\" & sTemp Else Dim Folder : Folder = Mid(sTemp, InStrRev(sTemp, "|") + 1) sLine = "|" & Mid(sTemp, 1, InStrRev(sTemp, "|") - 1) & "|" sPath = sPath & "\" & Folder End If oFso.CreateFolder sPath If CreateFolder(sLine, sPath) Then CreateFolder = True End if End If Set oFso = Nothing End Function Private Function ParentFolder(byVal sPath) Dim regEx Set regEx = New RegExp regEx.Pattern = "^(.*)\\[^\\]*$" regEx.Global = True regEx.IgnoreCase = True ParentFolder = regEx.Replace(sPath, "$1") Set regEx = Nothing End Function Private Function IsNothing(byVal sVar) IsNothing = CBool(sVar = Empty) End Function Private Function StrPadLeft(byVal sText, byVal sLen, byVal sChar) Dim sTemp : sTemp = sText Do While Len(sTemp) < sLen : sTemp = sChar & sTemp : Loop StrPadLeft = sTemp End Function Private Function StrToByte(byVal sText) For i = 1 To Len(sText) StrToByte = StrToByte & ChrB(Asc(Mid(sText, i, 1))) Next End Function Private Function ByteToStr(byVal sByte) Dim oStream Set oStream = Server.CreateObject("ADODB.Stream") oStream.Type = 2 oStream.Mode = 3 oStream.Open oStream.WriteText sByte oStream.Position = 0 oStream.CharSet = "gb2312" oStream.Position = 2 ByteToStr = oStream.ReadText oStream.Close Set oStream = Nothing End Function Private Function GetClientIPAddr If IsNothing(GetServerVar("HTTP_X_FORWARDED_FOR")) Then GetClientIPAddr = GetServerVar("REMOTE_ADDR") Else GetClientIPAddr = GetServerVar("HTTP_X_FORWARDED_FOR") End If End Function Private Function GetServerVar(byVal sText) GetServerVar = Request.ServerVariables(sText) End Function Private Function IPToNum(byVal sIp) Dim sIp_1, sIp_2, sIp_3, sIp_4 If IsNumeric(Left(sIp, 2)) Then sIp_1 = Left(sIp, InStr(sIp, ".") - 1) sIp = Mid(sIp, InStr(sIp, ".") + 1) sIp_2 = Left(sIp, InStr(sIp, ".") - 1) sIp = Mid(sIp, InStr(sIp, ".") + 1) sIp_3 = Left(sIp, InStr(sIp, ".") - 1) sIp_4 = Mid(sIp, InStr(sIp, ".") + 1) End If IPToNum = CInt(sIp_1) * 256 * 256 * 256 + CInt(sIp_2) * 256 * 256 + CInt(sIp_3) * 256 + CInt(sIp_4) - 1 End Function REM CLASS-TERMINATE Private Sub Class_Terminate Call DelProgress Form.RemoveAll Set Form = Nothing End Sub End Class %> 。
最后此篇关于php中关于普通表单多文件上传的处理方法的文章就讲到这里了,如果你想了解更多关于php中关于普通表单多文件上传的处理方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在 mongodb 中的玩家和锦标赛之间存在多对多关系。 我希望能够一次将许多玩家添加到锦标赛中。如果没有 ajax,这很简单,但我们有一个包含数千名玩家的数据库,因此表单选择变得巨大。 我们想为此
这个问题已经有答案了: When should I use html's and when spring's in Spring MVC web app? (3 个回答) 已关闭 6 年前。 我正
我正在 C++ Builder XE4 上使用 VCL。 我有以下组件。 FormMain 具有 TButton *B_select; FormSelect(或DialogSelect)具有 TCom
如何在不影响表单控件的情况下更改表单的 alphablend? 德尔福XE7 最佳答案 此问题的一个解决方案是使用多设备应用程序(如果无法使用VCL)。 如果您需要保留透明的TForm,只需更改属性T
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我正在尝试扩展 Django 注册以包含我自己的注册表单。原则上这是相当简单的。我只需要编写自己的表单( CustomRegistrationForm ),它是原始表单( RegistrationFo
我正在尝试为我的网站实现聊天功能。为了做到这一点,我遵循了以下教程:https://channels.readthedocs.io/en/latest/tutorial/ 然后我稍微更改了代码以实现它
有一个问题,我需要用一个 html 表单提交两个相互关联的模型表单。我知道如何提交两个单独的表格,但是在相关模型表格的情况下外键让我发疯。 问题是,第二个表单应该用外键填充字段到第一个表单的实例。 在
我正在创建一个工具,允许某人输入食谱,然后将其保存为 XML 文件,我已经创建了 XSD,但我想知道如何在我的网页上制作一个表单以允许用户输入他们的食谱并遵守模式。我一直在研究 Ajax 和 Jque
在 .net win 表单(如 asp.net web 表单)中是否有可用的验证控件? 因为很难为我的每个控件设置正确的条件,所以我的表单中也有很多重复的代码。 正确的做法是什么? 最佳答案 看看这个
我有一个简短的问题。我正在学习如何使用 javascript 制作注册表,发现此链接非常有用。 http://www.w3resource.com/javascript/form/javascript
我正在开发一个项目,该项目将使用循环将许多表单添加到 mysql 数据库中。在 javascript 部分中,我无法让 var i 在函数 updatesum() 中工作。有人可以帮我吗? 我试图避免
在我的应用程序上有一个包含 2 个字段和一个保存按钮的表单。 在我的 onClick 结束时我需要什么来将光标返回到第一个字段。 我有这个来清除它们 txtData.setText("
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
<input type="text" name="textfield" onKeyPress="javascript:alert(event.
我正在构建的网站有一个登录表单,作为所有其他模板扩展的 base.html 模板的一部分;因此,我需要以某种方式处理每个页面上的登录/注销逻辑。 目前每个页面都在单独的 View 中加载,那么实现它的
我有一个表单类,看起来像.. #forms.py class ExampleForm(forms.Form): color = forms.CharField(max_length=25)
有没有办法在表单定义中给表单一个特殊的错误渲染函数?在 customizing-the-error-list-format 下的文档中它展示了如何为表单提供特殊的错误呈现函数,但似乎您必须在实例化表单
我正在处理由多个页面组成的表单,我想解决验证问题。 当我点击提交按钮时,当前页面上的所有字段都会在下方显示错误消息,但是如果我更改页面,那么我需要再次点击提交,因为这些字段未设置为已触摸。 如果我可以
是否可以附加到继承表单的 exclude 或 widgets 变量? 到目前为止,我有以下设置。 class AddPropertyForm(forms.ModelForm): num_mon
我是一名优秀的程序员,十分优秀!