django使用ajax提交表单,django使用ajax
1.注册相关知识点1。表单组件
一般我们写窗体的时候都是在views视图里面写,所以不影响我们的视图功能。我们可以单独拿出来,在应用下构建一个forms.py文件来存储。
2.局部钩子函数
def clean_username(自己):
用户名=self.cleaned_data.get(用户名)
有效=型号。UserInfo.objects.filter(用户名=用户名)。首先()
如果有效:
引发验证错误(“用户名已经存在”)
返回用户名
3.全局钩子函数
#自定义全局钩子:验证两次密码是否相同。
def clean(自我):
if self . cleaned _ data . get( password )==self . cleaned _ data . get( password _ again ):
返回self.cleaned_data
否则:
引发验证错误(“两个密码不一致”)
4.与jQuery的属性操作相关
属性:
一个参数是获取属性值,两个参数是设置属性值。
RemoveAttr(属性名):
删除属性值
道具:
自适应属性的返回值是布尔值(单选、反向选择和取消的示例)。
removePorp:
删除属性的值。
5.两种流通方式:
$.each(数组/对象,函数(I,v){})
$(div )。每个(函数(I,v){})
6.css中的三种隐藏:
1.显示:无隐藏所有内容。
2.可见性:隐藏的隐藏内容
3.溢出:隐藏隐藏溢出的内容。
这三个都是用来隐藏的:
不同的是:
可见性是隐藏的,但是隐藏的内容仍然占据这个空间,隐藏的内容保留这个空间,这个空白的空间会在网页中显示出来。
和显示:隐藏占用的空间。
我们注册的时候不用display:none,不然选择文件的功能就没了。我们可以让它变得透明。
7.FormData用于提交二进制数据。
var formData=new formData();
formData.append(用户名,$( # id _用户名)。val());
formData.append(email ,$(#id_email )。val());
formData.append(tel ,$(#id_tel )。val());
formData.append(password ,$(#id_password )。val());
formdata . append( password _ again ,$(#id_password_again )。val());
formData.append(avatar_img ,$(#avatar)[0]。文件[0]);
记得补充
contentType:false
processData:false
8.你可以用下面的方法来判断请求是什么。
If request.ajax(): # If ajax请求
If,method== POST: #如果是POST请求
9.上传的文件有一个固定的配置参数media,它类似于但不同于static。
步骤如下:
-首先在设置中配置:
#========媒体配置=============
MEDIA_URL=/media/ # alias
Media _ root=OS . path . join(base _ dir, app01 , media , uploads) #特定路径-在url中配置
url(r^media/(?p路径。*) $ ,serve,{ document _ root :settings . media _ root }),有用:
有用性1:
-avatar=models . file field(verbose _ name= avatar ,upload _ to= avatar ,default=/avatar/default.png )
会把收到的文件放在media和upload _ to:base _ dir blog media uploads avatar/a . png指示的路径的串联中。
头像字段在数据库中保存为:avatar/a.png
有用性2:
- img src=/media/avatar/a.png
如果上传成功,图片会自动保存在这里。
10.头像图片预览
//头像预览
$(.avatar _ file’)。change(function () {
var ele_file=$(this)[0]。文件[0];//当前选择的文件
var reader=new FileReader();
reader . readasdataurl(ele _ file);//对应找到打开的网址
reader.onload=function () {
{#模式1 #}
$(.avatar _ img’)。attr(src ,this . result);//this.result是上面找到的url
{#模式2 #}
{# $(.avatar_img)[0]。src=this.result//设置图片属性#}
}
})
11.表单自动生成的错误消息
当你定义了一个全局钩子,而你的全局钩子函数中恰好有一个错误(例如,两个密码输入不一致),这样当你打印一个错误消息时
会有一个__all__对象,由你设置的全局钩子生成。
因此,我们不得不单独做出判断。现在只有一个全球挂钩。你可以这样判断。但是,当全局钩子很多的时候,就要分别判断了。
if (i==__all__){
$(#id_password_again )。之后(span)
}
二、注册操作URL的具体实现。pyfromdjango.conf.urlimporturl,包含
来自姜戈. contrib导入管理
从django.conf导入设置
静态导入服务
从博客导入视图
urlpatterns=[
url(r^admin/,管理网站网址),
url(r^login/,views.login),
url(r^index/,观点指数),
url(r^v_code/,views.v_code),
url(r^login2/,views.login2),
url(r^pcgetcaptcha/,views.pcgetcaptcha),
# 以上是论坛第75天的内容
url(r^reg/$,views.reg),
url(r^media/(?p路径. *)$ ,serve,{document_root :设置。媒体_根})
]
如果设置。调试:
导入调试工具栏
urlpatterns=[
url(r^__debug__,包含(debug _ toolbar.urls))
] urlpatterns
views.pydef reg(请求):
logger.info(又来了,小伙子)
collect_logger.info(小伙子又来洗。脚。了)
if request.method==POST :
ret={ret:0}
form_obj=表单RegForm(请求。帖子)
logger.debug(请求。文件)
if form_obj.is_valid():
# 数据经过校验没问题
伐木工。debug(form _ obj。已清理_数据)
avatar_obj=请求FILES.get(阿凡达)
# 创建用户
表单_对象。已清理_数据。pop( re _ password ,)
模特UserInfo.objects.create_user(
头像=avatar_obj
**form_obj.cleaned_data
)
ret[data]=/login/
否则:
# 数据校验失败
ret[code]=1
ret[data]=form_obj.errors
返回JSON响应(ret)
form_obj=表单RegForm()
return render(请求, reg.html ,{form_obj:form_obj})
forms . py来自django导入表单
从异常导入验证错误
验证器导入RegexValidator
从博客导入模型
# 登陆形式
类LoginForm(表单。表单):
用户名=表单。夏菲尔德(
标签=用户名,
最小长度=3,
最大长度=12,
错误消息={
必需的: 用户名不能为空,
最小长度: 用户名最短为3位,
最大长度: 用户名最长12位,
},
widget=forms.widgets.TextInput(
attrs={class: form-control}
)
)
密码=表单。夏菲尔德(
标签=密码,
最小长度=4,
最大长度=12,
错误消息={
必需的: 用户名不能为空,
最小长度: 用户名最短3位,
最大长度: 用户名最长12位,
},
小部件=表单。小部件。密码输入(
attrs={class: form-control}
)
)
# 注册形式
类RegForm(表单.表单):
用户名=表单。夏菲尔德(
标签=用户名,
最小长度=3,
最大长度=12,
错误消息={
必需的: 用户名不能为空!
最小长度: 用户名最短3位,
最大长度: 用户名最长12位
},
小部件=表单。小部件。textinput(attrs={ class : form-control })
)
密码=表单。夏菲尔德(
标签=密码,
最小长度=4,
最大长度=12,
错误消息={
必需的: 密码不能为空!
最小长度: 密码最短四位,
最大长度: 密码最长12位
},
小部件=表单。小部件。密码输入(attrs={ class : form-control })
)
re_password=forms .夏菲尔德(
标签=确认密码,
最小长度=4,
最大长度=12,
错误消息={
必需的: 确认密码不能为空!
最小长度: 密码最短四位,
最大长度: 密码最长12位
},
小部件=表单。小部件。密码输入(attrs={ class : form-control })
)
电话=表格。夏菲尔德(
标签=手机,
最小长度=11,
最大长度=11,
验证器=[
“RegexValidator(r^\d{11}$,”手机号必须是数字),
“regexvalidator(r^1[356789][0-9]{9}$,”无效的手机号码)
],
错误消息={
必需的:手机不能为空!
最小长度:手机号码11位,
最大长度:手机号码11位
},
widget=forms.widgets.TextInput(
attrs={class:form-control}
)
)
# 局部钩子
def clean _用户名(自己):
价值=自我。已清理_数据。get(用户名,)
如果金/瓶/梅价值:
引发验证错误(不符/合社/会/主/义/核心价值观)
否则如果模型UserInfo.objects.filter(用户名=值):
引发验证错误(用户名已存在)
否则:
返回值
# 全局钩子
定义清理(自我):
pwd=自我。已清理_数据。get(密码,)
re _ pwd=self。已清理_数据。get( re _ password ,)
如果重密码和密码==密码:
返回自我清理_数据
否则:
err_msg=两次输入密码不一致
self.add_error(re_password ,err_msg)
引发验证错误(错误消息)
reg.html!声明文档类型
html lang=en
头
meta charset=UTF-8
标题欢迎注册/标题
meta name= viewport content= width=device-width,initial-scale=1
link rel=样式表 href=/static/bootstrap-3。3 .7/CSS/自举。量滴 CSS
风格。reg-form {
边距-顶部:70px
}
#show-avatar {
宽度:80px
高度:80px
}
/风格
/头
身体
差异
差异
差异
表单自动完成=off novalidate
差异
的标签= { { form _ obj。用户名。id _ for _ label } }
{ { form _ obj。用户名。label } }/label
差异
{{ form_obj.username }}
span /span
/div
/div
差异
的标签= { { form _ obj。密码。id _ for _ label } }
{ { form _ obj。密码。label } }/label
差异
{{ form_obj.password }}
span /span
/div
/div
差异
的标签= { { form _ obj。re _ password。id _ for _ label } }
{ { form _ obj。re _ password。label } }/label
差异
{{ form_obj.re_password }}
span /span
/div
/div
差异
的标签= { { form _ obj。电话。id _ for _ label } }
{{ form_obj.phone.label }} /label
差异
{{ form_obj.phone }}
span /span
/div
/div
差异
标签头像/标签
差异
输入accept= image/* type= file id= id _ avatar name= avatar
的标签= id _ avatar img src=/static/img/default。png id=显示头像/label
/div
/div
差异
差异
按钮类型=button id=reg-button 注册/按钮
/div
/div
/表单
/div
/div
/div
脚本src=/static/jquery-3。3 .1 .量滴js /脚本
script src=/static/setup Ajax。js /脚本
脚本
//找到注册按钮绑定点击事件
$(#reg-button ).单击(函数(){
let data obj=new FormData();
dataObj.append(用户名,$( # id _用户名)。val());
dataObj.append(password ,$(#id_password )).val());
dataObj.append(re_password ,$(#id_re_password ).val());
dataObj.append(phone ,$(#id_phone ).val());
dataObj.append(avatar ,$(#id_avatar)[0].文件[0]);
$.ajax({
URL:"/reg/",
类型: POST ,
processData: false,
contentType: false,
数据:dataObj,
成功:函数(数据){
console.log(数据);
if(data.data) {
//如果有报错信息,应该在页面的对应的位置展示出来
设errMsgObj=data.data
$.each(errMsgObj,function(k,v){
$(#id_ k).下一个(。帮助-阻止)。文本(v[0]).父级()。父级()。addClass(" has-error ");
})
}否则{
控制台。日志(数据。数据);
位置。href=数据。data /log in/
}
}
})
});
//给每一个投入标签绑定集中事件,移除当前的错误提示信息
$(input.form-control ).focus(function() {
$(这个)。下一个(。帮助-阻止)。文本("")。父级()。父级()。移除类别(" has-error ")
});
//头像预览
$(#id_avatar ).change(function() {
//找到你选中的那个头像文件
让文件obj=this。文件[0];
控制台。日志(文件对象);
//读取文件路径
let fileReader=new fileReader();
文件阅读器。readasdataurl((file obj));
//等图片被读取完毕后,在进行操作
fileReader.onload=function() {
//设置预览图片
$(#show-avatar ).attr(src ,filereader。结果);
};
})
/脚本
/body
/html
models.pyfrom django.db导入模型
#在此创建您的模型。
从django.contrib.auth.models导入抽象用户
类UserInfo(AbstractUser):
用户信息表
nid=模型AutoField(primary_key=True)
电话=模型CharField(max_length=11,null=True,unique=True)
头像=模特. FileField(upload_to=avatars/,default=avatars/default.png )
博客=模特OneToOneField(to=Blog ,to_field=nid ,null=True)
def __str__(self):
返回自我。用户名
类别元:
详细名称=用户信息
详细名称复数=详细名称
班级博客(模特。型号):
博客信息
nid=模型AutoField(primary_key=True)
标题=模型CharField(max_length=64) #个人博客主题
主题=模型CharField(max_length=32) #每个博客主题
def __str__(self):
返回自我标题
类别元:
详细名称=博客
详细名称复数=详细名称
类别类别(型号。型号):
个人文章分类
nid=模型AutoField(primary_key=True)
标题=模型CharField(max_length=32) #分类主题
博客=模特ForeignKey(to=Blog ,to_field=nid) #外键关联博客,一个博客可以有多个分类
def __str__(self):
返回"{ 0 }-{ }"。格式(自我博客标题,自我标题)
类别元:
详细名称=文章分类
详细名称复数=详细名称
类别标签(型号。型号):
标贴
nid=模型AutoField(primary_key=True)
标题=模型CharField(max_length=32) #标签
博客=模特ForeignKey(to=Blog ,to_field=nid) #所属的博客
def __str__(self):
返回自我标题
类别元:
详细名称=标签
详细名称复数=详细名称
类文章(模型。型号):
文章
nid=模型AutoField(primary_key=True)
标题=模型CharField(max_length=64) #文章标题
desc=模特CharField(max_length=255) #文章描述
创建时间=模型datetime字段(auto _ now _ add=True)#创建时间
类别=型号ForeignKey(to=Category ,to_field=nid ,null=True)
用户=模型ForeignKey(to=UserInfo ,to_field=nid )
标签=型号ManyToManyField(
to=Tag ,
通过=第二条标签,
through_fields=(文章,标签)
)
def __str__(self):
返回自我标题
类别元:
详细名称=文章
详细名称复数=详细名称
类别文章详细信息(模型。型号):
文章详情表格
nid=模型AutoField(primary_key=True)
内容=模型。文本字段()
文章=模特OneToOneField(to=Article ,to_field=nid )
类别元:
详细名称=文章详情
详细名称复数=详细名称
第2类标签(型号。型号):
文章和标签多对多的关系
nid=模型AutoField(primary_key=True)
文章=模特ForeignKey(to=Article ,to_field=nid )
标签=型号ForeignKey(to=Tag ,to_field=nid )
def __str__(self):
返回"{ 0 }-{ }"。格式(自我文章、自我标签)
类别元:
unique_together=((article , tag ),)
详细名称=文章-标签
详细名称复数=详细名称
类文章下载(模型。型号):
点赞表
nid=模型AutoField(primary_key=True)
用户=模型ForeignKey(to=UserInfo ,null=True)
文章=模特ForeignKey(to=Article ,null=True)
is_up=型号BooleanField(默认值=真)
类别元:
unique_together=((article , user ))
详细名称=点赞
详细名称复数=详细名称
班级评论(模特。型号):
评论表
nid=模型AutoField(primary_key=True)
文章=模特ForeignKey(to=Article ,to_field=nid )
用户=模型ForeignKey(to=UserInfo ,to_field=nid )
内容=模型CharField(max_length=255)
创建时间=模型datetime字段(auto _ now _ add=True)
parent_comment=模型.ForeignKey(self ,null=True)
def __str__(self):
返回自我内容
类别元:
详细名称=评论
详细名称复数=详细名称
settings.py(带记录模块)
bbs_d76项目的姜戈设置。
由" django-管理startproject "使用Django 1.11.11生成。
有关此文件的更多信息,请参见
https://docs.djangoproject.com/en/1.11/topics/settings/
有关设置及其值的完整列表,请参见
https://docs.djangoproject.com/en/1.11/ref/settings/
导入操作系统
#像这样在项目内部构建路径:os.path.join(BASE_DIR,)
BASE _ DIR=OS。路径。dirname(OS。路径。dirname(OS。路径。ABS路径(_ _ file _ _))
#快速启动开发设置-不适合生产
#见https://份文件。django项目。com/en/1.11/how to/deployment/check list/
#安全警告:生产中使用的密钥要保密!
SECRET_KEY=jng4g!)5pve-0s7)6lv(nty7$jn^!p7ov $-*hdn@! kkg7q#e
#安全警告:不要在生产中打开调试的情况下运行!
调试=真
ALLOWED_HOSTS=[]
#应用程序定义
INSTALLED_APPS=[
django.contrib.admin ,
django.contrib.auth ,
django.contrib.contenttypes ,
django.contrib.sessions ,
django.contrib.messages ,
django.contrib.staticfiles ,
博客。应用程序。博客配置,
]
中间件=[
姜戈。中间件。安全。安全中间件,
姜戈。贡献。会话。中间件。会话中间件,
姜戈。中间件。常见。通用中间件,
姜戈。中间件。csrf。 csrfviewmiddleware ,
姜戈。贡献。auth。中间件。认证中间件,
姜戈。贡献。消息。中间件。消息中间件,
姜戈。中间件。点击顶举。xframeoptions中间件,
]
ROOT_URLCONF=bbs_d76.urls
模板=[
{
后端姜戈。模板。后端。姜戈。django模板,
DIRS: [os.path.join(BASE_DIR, templates)]
,
APP_DIRS :对,
选项:{
上下文处理者:[
姜戈。模板。上下文处理器。调试,
姜戈。模板。上下文处理器。请求,
姜戈。贡献。auth。上下文处理器。授权,
姜戈。贡献。消息。上下文处理器。消息,
],
},
},
]
WSGI _ APPLICATION= BBS _ d76。WSGI。应用程序
#数据库
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
数据库={
默认:{
引擎: django.db.backends.mysql ,
名称: bbs_d76 ,
用户:根,
密码: 1234567890 ,
主机: 127.0.0.1 ,
端口:3306,
}
}
#密码验证
# https://个文档。django项目。com/en/1.11/ref/settings/#验证密码验证器
AUTH _ PASSWORD _ validator=[
{
名字:姜戈。贡献。auth。密码验证.用户属性相似性验证器,
},
{
名字:姜戈。贡献。auth。密码验证.MinimumLengthValidator ,
},
{
名字:姜戈。贡献。auth。密码验证.CommonPasswordValidator ,
},
{
名字:姜戈。贡献。auth。密码验证.NumericPasswordValidator ,
},
]
#国际化
# https://docs.djangoproject.com/en/1.11/topics/i18n/
语言代码=en-us
TIME_ZONE=UTC
USE_I18N=True
USE_L10N=True
USE_TZ=True
#静态文件(CSS、JavaScript、图像)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL=/static/
STATICFILES_DIRS=[
os.path.join(BASE_DIR,静态)
]
# 指定一下认证使用自定义的用户信息表
AUTH_USER_MODEL=blog .用户信息
# 用户上传的文件配置项
MEDIA_URL=/media/
MEDIA _ ROOT=OS。路径。加入(BASE _ DIR, MEDIA )
# 日志配置
基本日志目录=操作系统。路径。联接(BASE _ DIR, LOG )
日志记录={
版本:1,
# 禁用已经存在的记录器实例
disable _ existing _ loggers :False,
# 定义日志格式化的工具
格式化程序:{
标准:{
format :[%(ASC time)s][%(线程名称)s:%(线程)d][task _ id:%(名称)s][%(文件名)s:%(行号)d]
[%(级别名)s][%(消息)s]
},
简单:{
格式:[%(级别名)s][%(时间)s][%(文件名)s:%(行号)d]%(消息)s
},
收集:{
格式":%(消息)s”
}
},
# 过滤
过滤器:{
require_debug_true :
():姜戈。utils。日志。 requiredebugtrue ,
},
},
# 日志处理器
处理程序:{
控制台:{
级别:调试,
过滤器:[require_debug_true],#只有在姜戈调试为真实的时才在屏幕打印日志
类":"日志记录 StreamHandler ,
格式化程序:简单
},
默认:{
级别:信息,
类“:”日志记录。经手人。旋转文件处理程序,#保存到文件,自动切
filename :OS。路径。join(BASE _ LOG _ DIR, info.log ),#日志文件
maxBytes: 1024 * 1024 * 50,#日志大小50米
backupCount: 3,
格式化程序:标准,
编码: utf-8 ,
},
错误:{
级别:错误,
类“:”日志记录。经手人。旋转文件处理程序,#保存到文件,自动切
filename :OS。路径。join(BASE _ LOG _ DIR, err.log ),#日志文件
maxBytes: 1024 * 1024 * 50,#日志大小50米
backupCount: 5,
格式化程序:标准,
编码: utf-8 ,
},
收集:{
级别:信息,
类“:”日志记录。经手人。旋转文件处理程序,#保存到文件,自动切
filename :OS。路径。join(BASE _ LOG _ DIR, xxx_collect.log ),
maxBytes: 1024 * 1024 * 50,#日志大小50米
backupCount: 5,
格式化程序:收集,
编码: utf-8
}
},
#记录器实例
"记录器":{
# 默认的记录器应用如下配置
: {
处理程序:[默认,控制台,错误],#上线之后可以把控制台移除
级别:调试,
传播:真,
},
# 名为收集的记录器还单独处理
收集:{
处理程序:[控制台,收集],
级别:信息,
}
},
}
INTERNAL_IPS=[127.0.0.1 ,]
涉及
转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。