Django—Form、ModelFor

  • 2020 年 1 月 16 日
  • 笔记

一、Form

form.py

from django import forms  from django.core.exceptions import ValidationError  from django.contrib.auth.models import User  import re      # 定义手机号验证规则  def phone_validate(value):      phone = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')      if not phone.match(value):          raise ValidationError("手机号格式错误")      class RegForm(forms.Form):      username = forms.CharField(          label="用户名",          min_length=6,          initial="请输入用户名",          error_messages={              'required': "不能为空",              "invalid": "格式错误",              "min_length": "用户名最短6位"          },          widget=forms.widgets.TextInput(attrs={"class": "form-control"})      )        password = forms.CharField(          label="密码",          min_length=8,          widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),          error_messages={              "required": "不能为空",              "min_length": "不能少于8位"          }      )        re_password = forms.CharField(          label="密码",          min_length=8,          widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),          error_messages={              "required": "不能为空",              "min_length": "不能少于8位"          }      )        email = forms.EmailField(          label="邮箱",          widget=forms.widgets.TextInput(attrs={"class": "form-control"}),          error_messages={              'required': "不能为空",              "invalid": "格式错误",          }      )        # radio      gender = forms.fields.ChoiceField(          choices=((1,"男"),(0,"女"),),          label="性别",          initial=1,          widget=forms.widgets.RadioSelect()      )        # 单选select      se_hobby = forms.fields.ChoiceField(          label="select单选爱好",          choices=((1,"篮球"),(2,"网球"),(3,"羽毛球"),),          # initial=1,          widget=forms.widgets.Select()      )        # 多选select      se_hobbys = forms.fields.MultipleChoiceField(          label="select多选爱好",          choices=((1, "篮球"), (2, "网球"), (3, "羽毛球"),),          initial=[1,],          widget=forms.widgets.SelectMultiple()      )        # 单选checkbox      keep_username = forms.fields.ChoiceField(          label="记住用户名",          # initial="checked",          widget=forms.widgets.CheckboxInput()      )        # 多选checkbox      ch_hobbys = forms.fields.MultipleChoiceField(          label="checkbox多选爱好",          choices=((1, "篮球"), (2, "网球"), (3, "羽毛球"),),          # initial=[1, 2],          widget=forms.widgets.CheckboxSelectMultiple()      )        # 手机号      phone = forms.fields.CharField(          validators=[phone_validate, ],          error_messages={              "required": "手机不能为空"          },          widget=forms.widgets.TextInput(attrs={"class": "form-control"})      )        # # 批量增加样式      # def __init__(self, *args, **kwargs):      #     super(RegForm, self).__init__(*args, **kwargs)      #     for field in iter(self.fields):      #         self.fields[field].widget.attrs.update({      #             'class': 'form-control'      #         })      #      #     # 动态获取数据库的choice数据      #     self.fields["gender"].choices = User.objects.all().values_list("id", "gender")          # 重写全局的钩子函数,对确认密码做校验      def clean(self):          password = self.cleaned_data.get("password")          re_password = self.cleaned_data.get("re_password")          if re_password and re_password != password:              self.add_error("re_password", ValidationError("两次输入的密码不一致"))          else:              return self.cleaned_data        # 定义局部钩子,验证用户名是否被注册      def clean_username(self):          username = self.cleaned_data.get("username")          is_exist = User.objects.filter(username=username)          if is_exist:              self.add_error("username", ValidationError("用户名已被注册"))          else:              return username        # 定义局部钩子,验证邮箱是否可用      def clean_email(self):          email = self.cleaned_data.get("email")          is_exist = User.objects.filter(email=email)          if is_exist:              self.add_error("email", ValidationError("邮箱不可用"))          else:              return email

View Code

view.py

def reg(request):      form_obj = RegForm()      if request.method == "POST":          ret = {"status": 0, "msg": ""}          form_obj = RegForm(request.POST)          if form_obj.is_valid():              # form_obj.cleaned_data.pop("re_password")              # print(form_obj.cleaned_data)              # User.objects.create_user(**form_obj.cleaned_data)              ret["msg"] = "/login"              return JsonResponse(ret)          else:              # print(form_obj.errors)              ret["status"] = 1              ret["msg"] = form_obj.errors              return JsonResponse(ret)      return render(request, 'register.html', {"forms_obj": form_obj})

View Code

register.html

<!DOCTYPE html>  <html lang="zh-CN">  <head>      <meta charset="UTF-8">      <title>Title</title>      <meta http-equiv='Content-type' content='text/htm'>      <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">      <script src="/static/jquery-3.3.1.js"></script>      <script src="/static/bootstrap/js/bootstrap.min.js"></script>  </head>  <body>  <div class="container">      <div class="row">          <div class="col-md-6 col-md-offset-3 reg-form">              <h3 class="text-center">Register</h3><br>              <form class="form-horizontal" novalidate  method="post"                    enctype="multipart/form-data">                  {% csrf_token %}                  <div class="form-group ">                      <label for='{{ forms_obj.username.id_for_label }}'                             class="col-sm-2 control-label">{{ forms_obj.username.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.username }}                          <span class="help-block">{{ forms_obj.username.errors.0 }}</span>                          <span id="ss" class="help-block"></span>                      </div>                  </div>                    <div class="form-group ">                      <label for='{{ forms_obj.password.id_for_label }}'                             class="col-sm-2 control-label">{{ forms_obj.password.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.password }}                          <span class="help-block">{{ forms_obj.password.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group ">                      <label for='{{ forms_obj.re_password.id_for_label }}'                             class="col-sm-2 control-label">{{ forms_obj.re_password.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.re_password }}                          <span class="help-block">{{ forms_obj.re_password.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.email.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.email.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.email }}                          <span class="help-block">{{ forms_obj.email.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.gender.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.gender.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.gender }}                          <span class="help-block">{{ forms_obj.gender.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.se_hobby.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.se_hobby.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.se_hobby }}                          <span class="help-block">{{ forms_obj.se_hobby.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.se_hobbys.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.se_hobbys.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.se_hobbys }}                          <span class="help-block">{{ forms_obj.se_hobbys.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.keep_username.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.keep_username.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.keep_username }}                          <span class="help-block">{{ forms_obj.keep_username.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.ch_hobbys.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.ch_hobbys.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.ch_hobbys }}                          <span class="help-block">{{ forms_obj.ch_hobbys.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.phone.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.phone.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.phone }}                          <span class="help-block">{{ forms_obj.phone.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <div class="col-sm-offset-3 col-sm-6">                          <button id="reg_submit" type="button" class="btn btn-success btn-block">注册</button>                      </div>                  </div>              </form>          </div>      </div>  </div>    <script>      $("#reg_submit").click(function () {          var formData = new FormData();          formData.append("username", $("#id_username").val());          formData.append("password", $("#id_password").val());          formData.append("re_password", $("#id_re_password").val());          formData.append("gender", $("input[name='gender']:checked").val());          formData.append("se_hobby", $("#id_se_hobby").val());          formData.append("se_hobbys", $("#id_se_hobbys").val());          formData.append("keep_username", $("#id_keep_username").prop("checked"));          formData.append("ch_hobbys", $("#id_ch_hobbys input[name='ch_hobbys']:checked").val());          formData.append("phone", $("#id_phone").val());          formData.append("csrfmiddlewaretoken", $("input[name='csrfmiddlewaretoken']").val());          $.ajax({              url:'/register/',              type:'post',              processData: false,              contentType: false,              data:formData,          }).done(function (data) {              if (data.status){                  $.each(data.msg,function (k,v) {                      $("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error")                  })              }              else {                  window.location.href = data.msg              }          })      });        $("form input").focus(function () {          $(this).next("span").text("").parent().parent().removeClass("has-error");      });      $("form select").focus(function () {          $(this).next("span").text("").parent().parent().removeClass("has-error");      });      $("form input[name='ch_hobbys']").focus(function () {          $(this).parents("ul").next("span").text("").parent().parent().removeClass("has-error");      })  </script>  </body>  </html>

View Code

二、ModelForm

form.py

from booktest.models import *  from django.forms import widgets as wds      class BookForm(forms.ModelForm):      class Meta:          model = BookInfo          fields = "__all__"          labels = {              "btitle": "书名",              "bpub_date": "发布日期",              "bcomment": "评论量",              "bread": "阅读量"          }            widgets = {              "btitle": wds.TextInput(attrs={"class": "form-control"}),              "bpub_date": wds.TextInput(attrs={"class": "form-control", "type": "date"}),              "bread": wds.TextInput(attrs={"class": "form-control"}),              "bcomment": wds.TextInput(attrs={"class": "form-control"})          }            error_messages = {              "btitle": {"required":"不能为空",},              "bpub_date": {"required":"不能为空",},              "bcomment": {"required":"不能为空",},              "bread": {"required":"不能为空",}          }

View Code

view.py(add_book)

def add_book(request):      form_obj = BookForm()      if request.method == "POST":          ret = {"status": 0, "msg": ""}          form_obj = BookForm(data=request.POST)          if form_obj.is_valid():              print(form_obj.cleaned_data)              form_obj.save()              ret["msg"] = '/bookform'              return JsonResponse(ret)          else:              ret["status"] = 1              ret["msg"] = form_obj.errors              return JsonResponse(ret)      return render(request, 'add_book.html', {"forms_obj": form_obj})

View Code

add_book.html

<!DOCTYPE html>  <html lang="zh-CN">  <head>      <meta charset="UTF-8">      <title>Title</title>      <meta http-equiv='Content-type' content='text/htm'>      <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">      <script src="/static/jquery-3.3.1.js"></script>      <script src="/static/bootstrap/js/bootstrap.min.js"></script>  </head>  <body>  <div class="container">      <div class="row">          <div class="col-md-6 col-md-offset-3 reg-form">              <h3 class="text-center"></h3><br>              <form class="form-horizontal" novalidate  method="post"                    enctype="multipart/form-data">                  {% csrf_token %}                  <div class="form-group ">                      <label for='{{ forms_obj.btitle.id_for_label }}'                             class="col-sm-2 control-label">{{ forms_obj.btitle.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.btitle }}                          <span class="help-block">{{ forms_obj.btitle.errors.0 }}</span>                          <span id="ss" class="help-block"></span>                      </div>                  </div>                    <div class="form-group ">                      <label for='{{ forms_obj.bpub_date.id_for_label }}'                             class="col-sm-2 control-label">{{ forms_obj.bpub_date.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.bpub_date }}                          <span class="help-block">{{ forms_obj.bpub_date.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group ">                      <label for='{{ forms_obj.bcomment.id_for_label }}'                             class="col-sm-2 control-label">{{ forms_obj.bcomment.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.bcomment }}                          <span class="help-block">{{ forms_obj.bcomment.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <label for="{{ forms_obj.bread.id_for_label }}"                             class="col-sm-2 control-label">{{ forms_obj.bread.label }}</label>                      <div class="col-sm-8">                          {{ forms_obj.bread }}                          <span class="help-block">{{ forms_obj.bread.errors.0 }}</span>                      </div>                  </div>                    <div class="form-group">                      <div class="col-sm-offset-3 col-sm-6">                          <button id="reg_submit" type="button" class="btn btn-success btn-block">注册</button>                      </div>                  </div>              </form>          </div>      </div>  </div>    <script>      $("#reg_submit").click(function () {          var formData = new FormData();          formData.append("btitle", $("#id_btitle").val());          formData.append("bpub_date", $("#id_bpub_date").val());          formData.append("bcomment", $("#id_bcomment").val());          formData.append("bread", $("#id_bread").val());          formData.append("csrfmiddlewaretoken", $("input[name='csrfmiddlewaretoken']").val());          $.ajax({              url:'/bookform/',              type:'post',              processData: false,              contentType: false,              data:formData,          }).done(function (data) {              if (data.status){                  $.each(data.msg,function (k,v) {                      $("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error")                  })              }              else {                  window.location.href = data.msg              }          })      });        $("form input").focus(function () {          $(this).next("span").text("").parent().parent().removeClass("has-error");      });  </script>  </body>  </html>

View Code

view.py(edit_book)

def editbook(request, book_id):      edit_book = BookInfo.objects.get(id=book_id)      if request.method == "POST":          form_obj = BookForm(request.POST, instance=edit_book)          if form_obj.is_valid():              form_obj.save()     # edit_book.update(request.POST)              return redirect('/add_book')      else:          form_obj = BookForm(instance=edit_book)          return render(request, 'edit_book.html', locals())

View Code

edit_book.html

<body>  <form method="post">      {% csrf_token %}      {% for field in form_obj %}      <div>      {{ field.label }}      {{ field }}<span>{{ field.errors.0 }}</span>      </div>      {% endfor %}      <input type="submit">  </form>    </body>

View Code