django使用ajax提交表单,django使用ajax

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: