django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用
一、modelForm操作及验证
1.获取数据库数据,界面展示数据并且获取前端提交的数据,并动态显示select框中的数据
views.py
from django.shortcuts import render,HttpResponse from app01 import models from django import forms from django.forms import fields as Ffields from django.forms import widgets as Fwidgets class UserInfoModelForm(forms.ModelForm): class Meta:#必须添加 model = models.UserInfo#指定去UserInfo表里获取数据 fields = '__all__' #在界面显示所有字段 # fields = ['username','email']#只在界面显示'username','email'字段 # exclude = ['username'] #不在界面显示'username'字段 class UserInfoForm(forms.Form): username = Ffields.CharField(max_length=32) email = Ffields.EmailField() user_type = Ffields.ChoiceField( choices=models.UserType.objects.values_list('id','caption')#以'id','caption'为select框中的数据 ) def __init__(self, *args, **kwargs): super(UserInfoForm,self).__init__(*args, **kwargs) self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')#加上这个init函数 #后,就能将新添加到数据库中的数据动态显示到select框啦 def index(request): if request.method == "GET":#将数据展示在界面 obj = UserInfoModelForm() return render(request,'index.html',{'obj': obj}) elif request.method == "POST":#获取前端提交的数据 obj = UserInfoModelForm(request.POST) if obj.is_valid():#obj.is_valid()只能为true或false print(obj.is_valid()) print(obj.cleaned_data) #obj.cleaned_data以字典的形式展示前端提交的数据 print(obj.errors.as_json())#打印错误信息 return render(request,'index.html',{'obj': obj})
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/index/" method="POST"> {% csrf_token %} {{ obj.as_p }} #以p标签的形式展示数据 <input type="submit" value="提交" /> </form> </body> </html>
二、完整的在界面展示数据、修改数据、提交数据、跳转到新页面
views.py
from django.shortcuts import render,HttpResponse from app01 import models from django import forms from django.forms import fields as Ffields#给导入的fields设置别名为Ffields from django.forms import widgets as Fwidgets#给导入的widgets设置别名为Fwidgets class UserInfoModelForm(forms.ModelForm): is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())#自定义在界面显示的单选框等,而且不用保存在数据库 class Meta:#class Meta里一定不要加逗号 model = models.UserInfo#指定去UserInfo表里获取数据 fields = '__all__' #在界面显示所有字段 # fields = ['username','email']#只在界面显示'username','email'字段 # exclude = ['username'] #不在界面显示'username'字段 labels = {#设定输入框的标签名 'username': '用户名', 'email': '邮箱', } help_texts = {#在输入框后面自定义帮助信息 'username': '我是帮助信息' } widgets = {#自定义输入框的属性,即自定义html标签的class 'username': Fwidgets.Textarea(attrs={'class': 'c1'})#将输入框设置为text文本框,并添加css:‘c1’ } error_messages = {#自定义错误信息提示 '__all__':{#给整体设置错误信息,跟form中的all一样 }, 'email': {#给每个字段设定错误信息 'required': '邮箱不能为空', 'invalid': '邮箱格式错误..', } } field_classes = {#将email输入框的格式验证修改为必须输入URL格式才正确 # 'email': Ffields.URLField } localized_fields=('ctime',)#将数据库时间转化为北京时间,括号里写需要转化时间的字段,需要在settings里设置 #timezone class UserInfoForm(forms.Form): username = Ffields.CharField(max_length=32) email = Ffields.EmailField() user_type = Ffields.ChoiceField( choices=models.UserType.objects.values_list('id','caption')#以'id','caption'为select框中的数据 ) def __init__(self, *args, **kwargs): super(UserInfoForm,self).__init__(*args, **kwargs) self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')#加上这个init函数 #后,就能将新添加到数据库中的数据动态显示到select框啦 def index(request):#将数据展示在界面 if request.method == "GET": obj = UserInfoModelForm() return render(request,'index.html',{'obj': obj}) elif request.method == "POST": obj = UserInfoModelForm(request.POST) if obj.is_valid():#obj.is_valid()只能为true或false obj.save()#自动将前端提交的数据保存在数据库 # print(obj.cleaned_data) #obj.cleaned_data以字典的形式获取前端提交的数据 # print(obj.errors.as_json()) return render(request,'index.html',{'obj': obj}) def user_list(request): li = models.UserInfo.objects.all().select_related('user_type')#获取UserInfo表中的所有数据,并且跨表将与UserInfo # 关联的user_type表中的数据也取出来,注意括号中写UserInfo类中的关联字段名,不可以写多对多的字段名,否则报错, #前端html跨表取user_type表数据:{% for row in li %} {{ row.user_type.caption }} return render(request,'user_list.html',{'li': li}) def user_edit(request, nid): # 1.获取当前id对应的用户信息 # 2.显示用户已经存在数据 if request.method == "GET":#数据展示 user_obj = models.UserInfo.objects.filter(id=nid).first()#根据nid获取UserInfo表中的相关数据的第一条 mf = UserInfoModelForm(instance=user_obj)#将mf传到前端就可以自动生成网页,括号中的instance参数是显示默认值 return render(request,'user_edit.html',{'mf': mf, 'nid': nid})#跳转回本页面,也可以跳转到其他页面 elif request.method == 'POST':#数据修改 user_obj = models.UserInfo.objects.filter(id=nid).first() mf = UserInfoModelForm(request.POST,instance=user_obj)#如果不加这句,就会自动在数据库中新添加数据,而不是修改 #已存在的数据 if mf.is_valid(): mf.save()#将修改的数据写入到数据库中 else:#如果出现异常,打印错误信息 print(mf.errors.as_json()) return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
urls.py
url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^user_list/', views.user_list), url(r'^edit-(\d+)/', views.user_edit),
index.html
同上
user_list.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <ul> {% for row in li %} <li>{{ row.username }} - {{ row.user_type.caption }} - <a href="/edit-{{ row.id }}/">编辑</a></li> {% endfor %} </ul> </body> </html>
user_edit.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form method="POST" action="/edit-{{ nid }}/"> #以新链接的形式提交数据 {% csrf_token %} {{ mf.as_p }} <input type="submit" value="提交" /> </form> </body> </html>
三、ajax操作发送表单,并且获取数据,页面不刷新
1.给后台发送普通数据
views.py
def ajax(request): return render(request, 'ajax.html') def ajax_json(request): import time print(request.POST) ret = {'code': True , 'data': request.POST.get('username')} import json return HttpResponse(json.dumps(ret))
ajax.html
有两种ajax提交方式:推荐用第一种
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="text"/> <input type="button" value="Ajax1" onclick="Ajax1();" /> 第二种:ifram提交数据 <form action="/ajax_json/" method="POST" target="ifm1"> <iframe id="ifm1" name="ifm1" ></iframe> <input type="text" name="username" /> <input type="text" name="email" /> <input type="submit" onclick="sumitForm();" value="Form提交"/> </form> <script type="text/javascript" src="/static/jquery-1.12.4.js"></script> <script> 第一种:ajax提交表单数据 function getXHR(){ var xhr = null; if(XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } return xhr; } function Ajax1(){ var xhr = getXHR(); //var xhr = new XMLHttpRequest(); xhr.open('POST', '/ajax_json/',true);#括号内参数依次为:数据提交方式、提交去处、是否异步,true为异步 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完毕 var obj = JSON.parse(xhr.responseText); console.log(obj); } }; xhr.setRequestHeader('k1','v1'); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); xhr.send("name=root;pwd=123"); } {# 第二种:ifram提交表单数据#} function sumitForm(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); }) } </script> </body> </html>
ifram详解:
<body> <form action="/ajax_json/" method="POST" target="ifm1">#表单提交到/ajax_json/ target:在指定的框架中打开 <iframe id="ifm1" name="ifm1" ></iframe> #加上display:none就看不到ifram框啦 <input type="text" name="username" /> <input type="text" name="email" /> <input type="submit" onclick="sumitForm();" value="Form提交"/> </form> <script> function sumitForm(){#获取ifram框架中的数据 $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); #.contents():由于ifram生成的是完整的html网页,通过contents()属性提取出网页内容,再找到body标签, #再通过text方法找到后台返回的数据 var obj = JSON.parse(text); #将获取到的后台数据json序列化 }) } </script>
2.给后台上传文件,上传文件有三种方式,优先使用ifram,再次使用jQuery ajax
views.py
def upload(request): return render(request,'upload.html') def upload_file(request): username = request.POST.get('username') fafafa = request.FILES.get('fafafa') import os img_path = os.path.join('static/imgs/',fafafa.name)#生成图片保存路径 with open(img_path,'wb') as f: for item in fafafa.chunks():#保存文件,必须用chunks() f.write(item) ret = {'code': True , 'data': img_path}#将图片路径返回给前端 import json return HttpResponse(json.dumps(ret))
upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .upload{ display: inline-block;padding: 10px; background-color: brown; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 90; } .file{ width: 100px;height: 50px;opacity: 0; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 100; } </style> </head> <body> <div style="position: relative;width: 100px;height: 50px;"> <input class="file" type="file" id="fafafa" name="afafaf" /> <a class="upload">上传</a> </div> 第一种上传方式:原生ajax <input type="button" value="提交XHR" onclick="xhrSubmit();" /> 第二种上传方式:jQuery ajax <input type="button" value="提交jQuery" onclick="jqSubmit();" /> <hr/> 分隔符 第三种上传方式:ifram 最好用第三和第二种 <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1"> <iframe id="ifm1" name="ifm1" style="display: none;"></iframe> <input type="file" name="fafafa" onchange="changeUpalod();" /> <input type="submit" onclick="iframeSubmit();" value="Form提交"/> </form> <div id="preview"></div> <script src="/static/jquery-1.12.4.js"></script> <script> 这一步可以不要,选中图片后自动提交,并且生成图片预览 function changeUpalod(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); 获取图片路径 $('#preview').empty(); #将预览图片标签清空 var imgTag = document.createElement('img'); 生成图片标签 imgTag.src = "/" + obj.data; 生成图片路径 $('#preview').append(imgTag); }); $('#form1').submit(); } 以下有三种文件提交方式,优先使用ifram,再次使用jQuery提交文件 以下这一步是:jQuery提交文件 function jqSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); fd.append('username','root'); fd.append('fafafa',file_obj); $.ajax({ url: '/upload_file/', type: 'POST', data: fd, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success:function(arg,a1,a2){ console.log(arg); console.log(a1); console.log(a2); } }) } 以下这一步是:原生ajax提交文件 function xhrSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); fd.append('username','root'); fd.append('fafafa',file_obj); var xhr = new XMLHttpRequest(); xhr.open('POST', '/upload_file/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完毕 var obj = JSON.parse(xhr.responseText); console.log(obj); } }; xhr.send(fd); } 以下这一步是:ifram提交文件,优先使用ifram提交 function iframeSubmit(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); 获取图片路径 $('#preview').empty(); #将预览图片标签清空 var imgTag = document.createElement('img'); 生成图片标签 imgTag.src = "/" + obj.data; 生成图片路径 $('#preview').append(imgTag); }); } </script> </body> </html>
四、生成图片验证码
check_code.py
#!/usr/bin/env python # -*- coding:utf-8 -*- import random from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z _upper_cases = _letter_cases.upper() # 大写字母 _numbers = ''.join(map(str, range(3, 10))) # 数字 init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) def create_validate_code(size=(120, 30), chars=init_chars, img_type="GIF", mode="RGB", bg_color=(255, 255, 255), fg_color=(0, 0, 255), font_size=18, font_type="Monaco.ttf", length=4, draw_lines=True, n_line=(1, 2), draw_points=True, point_chance=2): """ @todo: 生成验证码图片 @param size: 图片的大小,格式(宽,高),默认为(120, 30) @param chars: 允许的字符集合,格式字符串 @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG @param mode: 图片模式,默认为RGB @param bg_color: 背景颜色,默认为白色 @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF @param font_size: 验证码字体大小 @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf @param length: 验证码字符个数 @param draw_lines: 是否划干扰线 @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效 @param draw_points: 是否画干扰点 @param point_chance: 干扰点出现的概率,大小范围[0, 100] @return: [0]: PIL Image实例 @return: [1]: 验证码图片中的字符串 """ width, height = size # 宽高 # 创建图形 img = Image.new(mode, size, bg_color) draw = ImageDraw.Draw(img) # 创建画笔 def get_chars(): """生成给定长度的字符串,返回列表格式""" return random.sample(chars, length) def create_lines(): """绘制干扰线""" line_num = random.randint(*n_line) # 干扰线条数 for i in range(line_num): # 起始点 begin = (random.randint(0, size[0]), random.randint(0, size[1])) # 结束点 end = (random.randint(0, size[0]), random.randint(0, size[1])) draw.line([begin, end], fill=(0, 0, 0)) def create_points(): """绘制干扰点""" chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] for w in range(width): for h in range(height): tmp = random.randint(0, 100) if tmp > 100 - chance: draw.point((w, h), fill=(0, 0, 0)) def create_strs(): """绘制验证码字符""" c_chars = get_chars() strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开 font = ImageFont.truetype(font_type, font_size) font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3), strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines: create_lines() if draw_points: create_points() strs = create_strs() # 图形扭曲参数 params = [1 - float(random.randint(1, 2)) / 100, 0, 0, 0, 1 - float(random.randint(1, 10)) / 100, float(random.randint(1, 2)) / 500, 0.001, float(random.randint(1, 2)) / 500 ] img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) return img, strs
views.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from io import BytesIO from django.shortcuts import HttpResponse from django.shortcuts import render from utils.check_code import create_validate_code def check_code(request):#该函数对应login.html中的src=/check_code.html """ 验证码 :param request: :return: """ # stream = BytesIO() # img, code = create_validate_code() # img.save(stream, 'PNG') # request.session['CheckCode'] = code # return HttpResponse(stream.getvalue()) # data = open('static/imgs/avatar/20130809170025.png','rb').read() # return HttpResponse(data) # 1. 创建一张图片 pip3 install Pillow # 2. 在图片中写入随机字符串 # obj = object() # 3. 将图片写入到制定文件 # 4. 打开制定目录文件,读取内容 # 5. HttpResponse(data) stream = BytesIO()#生成一个内存对象 img, code = create_validate_code() #生成图片和验证码 img.save(stream,'PNG')#将图片保存到内存中,格式为png request.session['CheckCode'] = code #将验证码放到session里 return HttpResponse(stream.getvalue())#stream.getvalue()将图片从内存中取出,返回给前端 def login(request): """ 登陆 :param request: :return: """ # if request.method == "POST": # if request.session['CheckCode'].upper() == request.POST.get('check_code').upper(): # pass # else: # print('验证码错误') if request.method == 'POST': code = request.POST.get('check_code') if code.upper() == request.session['CheckCode'].upper(): print('验证码正确') else: print('验证码错误') return render(request, 'login.html') def register(request): """ 注册 :param request: :return: """ return render(request, 'register.html') def logout(request): """ 注销 :param request: :return: """ pass
login.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> <link rel="stylesheet" href="/static/css/edmure.css"/> <link rel="stylesheet" href="/static/css/commons.css"/> <link rel="stylesheet" href="/static/css/account.css"/> <style> </style> </head> <body> <div class="login"> <div style="font-size: 25px; font-weight: bold;text-align: center;"> 用户登陆 </div> <form role="form" action="/login.html" method="POST"> {% csrf_token %} <div class="form-group"> <label for="username">用户名</label> <input type="text" class="form-control" placeholder="请输入用户名"> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" class="form-control" placeholder="请输入密码"> </div> <div class="form-group"> <label for="password">验证码</label> <div class="row"> <div class="col-xs-7"> <input type="text" class="form-control" placeholder="请输入验证码" name="check_code"> </div> <div class="col-xs-5"> <img src="/check_code.html" onclick="changeCheckCode(this);"> #绑定事件,点击图片生成新的验证码 </div> </div> </div> <div class="checkbox"> <label> <input type="checkbox"> 一个月内自动登陆 </label> <div class="right"> <a href="#">忘记密码?</a> </div> </div> <button type="submit" class="btn btn-default">登 陆</button> </form> </div> <script> function changeCheckCode(ths){ ths.src = ths.src + '?'; {# 通过在url后边加问号的形式,实现点击验证码图片刷新页面获取新的验证码#} } </script> </body> </html>
五、富文本框使用
http://www.cnblogs.com/wupeiqi/articles/6307554.html 视频24天-17-KindEditor基本使用和文件操作
django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用的更多相关文章
- AJAX 表单提交 文件上传
1. AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载 ...
- jquery ajax file upload NET MVC 无刷新文件上传
网上有各种各样的文件上传方法,有基于JS框架的.也有基于flash swf插件的. 这次分享一个比较简单而且实用能快速上手的文件上传方法,主要步骤: 1.引用Jquery包,我用的是jquery-1. ...
- 使用jquery的ajax提交文件上传
以前的项目大多的使用jquery的插件来进行文件上传,对于就只引用jquery而不使用插件来上传文件之前未有写过,最近项目里有写到和用到,就记录一下,以后方便查找. 提示:存在浏览器皆容问题,谨慎使用 ...
- 通过jQuery Ajax提交表单数据时同时上传附件
1.使用场景:需要使用ajax提交表单,但是提交的表单里含有附件上传 2.代码实现方式: <!-- HTML代码 --> <form method="post" ...
- 传统表单提交文件上传,以及FormData异步ajax上传文件
传统的文件上传: 只用将form表单的entype修改成multipart/form-data,然后就可以进行文件上传,这种方式常用并且简单. 以下是另一种方式FormData,有时候我们需要ajax ...
- Ajax 提交表单【包括文件上传】
利用js插件实现 <script src="@Url.Content("~/js/layer/jquery.form.min.js")"></ ...
- mvc ---- ajax 提交 (ckeditor)富文本框 提示潜在危险 Request.Form
ajax 提交 ckeditor 中的内容怎么提交都提交不了,折腾半天,后来终于找到问题 在你的方法头上加 [HttpPost] [ValidateInput(false)] public Actio ...
- ajax/fetch上传富文本时出现中文乱码的解决方案(百分号问题)
最近正在编写自己的项目,其中遇到了nodejs后台接受到的富文本参数显示中文乱码的问题 一开始我以为是字符编码方式的错误,于是在请求参数的地方设置了utf-8,也就是: headers: { 'Con ...
- ajax+php (jquery.form插件)实现异步文件上传
<!DOCTYPE html> <html lang="CN"> <head> <title>upload model</ti ...
- PHP文件上传和文件操作案例
<?php /* *文件配置变量$dirname是目录名称 */ session_start(); $dirname = 'upload'; $fileClass = new fileClass ...
随机推荐
- 死磕Java之聊聊ArrayList源码(基于JDK1.8)
工作快一年了,近期打算研究一下JDK的源码,也就因此有了死磕java系列 ArrayList 是一个数组队列,相当于动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractLis ...
- javascript 文件的操作
js 文件的操作(ActiveXObject仅支持IE) 一.参数解释: 1. filename: filename //文件路径 2.iomode: var forReading=1;只读var f ...
- C语言字符串拼接
1.使用strcat进行字符串拼接 #include <stdio.h> #include <stdlib.h> #include <string.h> int m ...
- 题解 P1339 【[USACO09OCT]热浪Heat Wave】
题目链接 这道题纯属是一个裸的SPFA: 建议先把模板AC之后再做. 只需要做一些手脚,就是在加边的时候加一个双向边就好. 然后再第一次加点的时候 看不懂模板的出门左转度娘. 推荐下面一片讲解: 友链 ...
- quartz实例以及主要事项(注解)
实现任务类: package com.vnetoo.nec.base.quartz; import org.springframework.context.annotation.Lazy;import ...
- 品味ZooKeeper之Watcher机制_2
品味ZooKeeper之Watcher机制 本文思维导图如下: 前言 Watcher机制是zookeeper最重要三大特性数据节点Znode+Watcher机制+ACL权限控制中的其中一个,它是zk很 ...
- XAF ORMDataModel构建的基础资料对象无法被调用显示的解决办法
修正,其实只要在基础资料类中加入[XafDefaultProperty("名称")]标签即可. namespace NEO.ERP.Module.BusinessObjects.B ...
- mysql5.6 的st_distance 实现按照距离远近排序。
当前所处在的位置(113.858202 , 22.583819 ),需要查询我附近1000米内的小区,并安装由近到远的顺序排列 SELECT s.id,s.name,s.lng,s.lat, rou ...
- Flask之flask_script
flask端口占用 解决方案: lsof -i:5000 #查询是哪个进程占用的 kill PID 杀掉进程 flask_script之Manager类 from flask import Flask ...
- C++ 构造函数与默认构造函数
构造函数:C++用于构建类的新对象时需要调用的函数,该函数无返回类型!(注意:是“无”! 不是空!(void)). 默认构造函数:未提供显式初始值时,用来穿件对象的构造函数. 以上是二者的定义,但是单 ...