美文网首页
12.django自带form表单

12.django自带form表单

作者: 爱修仙的道友 | 来源:发表于2019-03-10 19:25 被阅读0次

django中提供了一个form表单的功能,这个表单可以用来验证数据的合法性还可以用来生成HTML代码

  • 关于django form表单的使用:
  1. 创建一个forms.py的文件,放在指定的app当中,然后在里面写表单.
  2. 表单是通过类实现的,继承自forms.Form,然后在里面定义要验证的字段.
  3. 在表单中,创建字段跟模型是一模一样的,但是没有null=True或者blank=True等这几种参数了,有的参数是required=True/False.
  4. 使用is_valid()方法可以验证用户提交的数据是否合法,而且HTML表单元素的name必须和django中的表单的name保持一致,否则匹配不到.
  5. is_bound属性:用来表示form是否绑定了数据,如果绑定了,则返回True,否则返回False.
  6. cleaned_data:这个是在is_valid()返回True的时候,保存用户提交上来的数据.

普通表单

  • 注册校验
  • views.py
class Register(View):
    def get(self, request):
        # 表单渲染注册界面
        form = RegisterForm()
        return render(request, 'register/register.html',context={
            'form':form,
        })
    def post(self, request):
        # 表单校验数据
        form = RegisterForm(request.POST)
        # 如果数据正确
        if form.is_valid():
            return HttpResponse('注册成功')

        # 若校验失败,则渲染注册界面
        return render(request, 'register/register.html', context={
            'form': form,
        })
  • form.py
from django import forms

# 普通表单校验
class RegisterForm(forms.Form):
    username = forms.CharField(label="用户名",max_length=20,required=True)
    password = forms.CharField(label="密码",max_length=20,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请输入长度为6-20位的密码'}),
                               error_messages = {
                                   'max_length':'密码长度小于6位',
                                   'min_length':'密码长度大于8位',
                                   'required':'必须传入'
                               })
    password_repeat = forms.CharField(label="请再次输入密码",max_length=20,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请输入长度为6-20位的密码'}),
                               error_messages = {
                                   'max_length':'密码长度小于6位',
                                   'min_length':'密码长度大于8位',
                               })

  • register.html
{% block content %}
<form class="form-horizontal" method="post">
  {% csrf_token %}

{{ form.as_p }}
{{ detail_form.as_p }}

  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-2 col-xs-2 ">
      {% if student_id %}
        <button type="submit" class="btn btn-default">更新</button>
      {% else %}
        <button type="submit" class="btn btn-default">保存</button>
      {% endif %}

    </div>
  </div>
</form>
{% endblock %}
  • 展示


    image.png

模型表单

  • 具体展示
from django import forms
from news.models import News, Tag


class NewsPubForm(forms.ModelForm):
    """
    """
   # 创建模型时,允许为空,所以需要重写,定义不能为空
    image_url = forms.URLField(label='文章图片url',
                               error_messages={"required": "文章图片url不能为空"})
    # 限制tag_id范围,tag是外键指定的多个值的多选框,所以定义的字段类型为ModelChoiceField
    tag = forms.ModelChoiceField(queryset=Tag.objects.only('id').filter(is_delete=False),
                                 error_messages={"required": "文章标签id不能为空", "invalid_choice": "文章标签id不存在", }
                                 )

    class Meta: # 元数据信息
        # 指定那个数据库模型来创建表单
        model = News  # 与数据库模型关联
        # 需要关联的字段
        # exclude 排除
        # 此处tag 指的是文章分类的实例对象,并不是tag_id,会出问题
        fields = ['title', 'digest', 'content', 'image_url', 'tag']
        # 自定义报错信息(由于定义模型没有写,所以在此处写)
        error_messages = {
            'title': {
                'max_length': "文章标题长度不能超过150",
                'min_length': "文章标题长度大于1",
                # 传入字符串为空和,传入为空格是有区别的
                'required': '文章标题不能为空',
            },
            'digest': {
                'max_length': "文章摘要长度不能超过200",
                'min_length': "文章标题长度大于1",
                'required': '文章摘要不能为空',
            },
            'content': {
                'required': '文章内容不能为空',
            },
        }
  • 学生信息修改
  • views.py
class NewStudentEdit(View):

    def get(self, request, student_id):
        student = models.Student.objects.select_related('studentdetail','area').filter(is_delete=False,id=student_id).first()
        # 用对象将form表单填充
        form = StudentForm(instance=student)

        try:
            detail_form = StudentDetailForm(instance=student.studentdetail)
        except:
            # 说明该学生对象并未创建学生详情,
            student_detail = models.StudentDetail()
            student_detail.student = student
            student_detail.save()
            detail_form = StudentDetailForm(instance=student.studentdetail)

        courses = models.Course.objects.all()
        area = models.Area.objects.all()
        return render(request,'students/new_edit.html',locals())
  • form.py
# 模型表单校验
class StudentForm(forms.ModelForm):

    class Meta:
        model = Student
        exclude = ['is_delete']

class StudentDetailForm(forms.ModelForm):

    class Meta:
        model = StudentDetail
        exclude = ['is_delete']
  • html

{% extends 'base/base.html' %}
{% block title %}
  学生详情
{% endblock %}

{% block section %}
{{ section }}
{% endblock %}

{% block content %}
<form class="form-horizontal" method="post">
  {% csrf_token %}

{{ form.as_p }}
{{ detail_form.as_p }}

  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-2 col-xs-2 ">
      {% if student_id %}
        <button type="submit" class="btn btn-default">更新</button>
      {% else %}
        <button type="submit" class="btn btn-default">保存</button>
      {% endif %}

    </div>
  </div>
</form>
{% endblock %}
  • 展示


    image.png
  • 自定义样式


{% extends 'base/base.html' %}
{% block title %}
  学生详情
{% endblock %}

{% block section %}
{{ section }}
{% endblock %}

{% block content %}
<form class="form-horizontal" method="post">
  {% csrf_token %}
{# 循环表单里每个字段 #}
  {% for filed in form %}
    <div class="form-group">
    {#  渲染错误  #}
    {% for err in filed.errors %}
      <label class="control-label" for="{{ filed.id_for_label }}">{{ err }}</label>
    {% endfor %}

    <label for="{{ filed.id_for_label }}" class="col-sm-2 control-label">{{ filed.label }}</label>
    <div class="col-sm-2">
      {{ filed }}
    </div>
  </div>
    
  {% endfor %}

# 未自定义样式
{{ detail_form.as_p }}

  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-2 col-xs-2 ">
      {% if student_id %}
        <button type="submit" class="btn btn-default">更新</button>
      {% else %}
        <button type="submit" class="btn btn-default">保存</button>
      {% endif %}

    </div>
  </div>
</form>
{% endblock %}
  • 展示
    [图片上传中...(image.png-3de43e-1552226626511-0)]

自定义验证

class NewStudentAdd(View):
    def post(self, request):

        form = StudentForm(request.POST)
        detail_form = StudentDetailForm(request.POST)

        if form.is_valid() and detail_form.is_valid():
            student = form.save()
            # 加上commit=False,不会去真的保存数据库
            # 因为还要加上外键关联对象
            student_detail = detail_form.save(commit=False)
            student_detail.student = student
            student_detail.save()
            return redirect(reverse('index:index'))

        return render(request, 'students/new_edit.html', locals())


class NewStudentEdit(View):

    def get(self, request, student_id):
        student = models.Student.objects.select_related('studentdetail','area').filter(is_delete=False,id=student_id).first()
        # 用对象将form表单填充
        form = StudentForm(instance=student)

        try:
            detail_form = StudentDetailForm(instance=student.studentdetail)
        except:
            # 说明该学生对象并未创建学生详情,
            student_detail = models.StudentDetail()
            student_detail.student = student
            student_detail.save()
            detail_form = StudentDetailForm(instance=student.studentdetail)

        courses = models.Course.objects.all()
        area = models.Area.objects.all()
        return render(request,'students/new_edit.html',locals())

    def post(self, request, student_id):
        student = models.Student.objects.select_related('studentdetail', 'area').filter(is_delete=False,
                                                                                        id=student_id).first()
        # 用对象将form表单填充
        form = StudentForm(request.POST, instance=student)
        detail_form = StudentDetailForm(request.POST, instance=student.studentdetail)

        if form.is_valid() and detail_form.is_valid():
            form.save()
            detail_form.save()
            return redirect(reverse('index:index'))

        return render(request, 'students/new_edit.html', locals())

  • 展示


    image.png
    image.png

模型表单的单字段和多字段校验

# 模型表单校验
class StudentForm(forms.ModelForm):

    class Meta:
        model = Student
        exclude = ['is_delete']

    # 自定义单字段校验
    def clean_name(self):
        name = self.cleaned_data.get('name')
        if not name[:-1].isdigit():
            raise forms.ValidationError('输入用户名不能为数字')

        return name
  • 展示


    image.png

相关文章

网友评论

      本文标题:12.django自带form表单

      本文链接:https://www.haomeiwen.com/subject/koprpqtx.html