Day 55 form组件

1. form组件创建页面的四种使用方式:

1.1方式一;手动写

<!-- novalidate 告诉浏览器不要去给我校验-->
<!-- 方式一    : 手写HTMl-->
<form action="" method="POST" novalidate>
{% csrf_token %}
<!-- novalidate 告诉浏览器不要去给我校验-->
<!-- 方式一 : 手写HTMl-->
<!-- <p>用户名:<input type="text" name="username"></p>-->
<!-- <p>年龄:<input type="text" name="age"></p>-->
<!-- <p>工资: <input type="text" name="salary"></p>-->
<!-- <input type="submit">-->
 

 此时视图函数中的代码:

1.2 利用自定义的form组件类在视图函数创建一个对象填充到前端页面当中去

视图函数中的代码:

def add_emp(request):
    if request.method == "GET":
        form = EmpForm()
        return render(request, "add_emp.html", {"form": form})

 

 

前端add_emp.html的代码:

方式二:

 <form action="" method="POST" novalidate>
                {% csrf_token %}
<!--    方式二:form自带的as_p-->
<!--        {{ form.as_p }}-->
<!--<input type="submit">

 方式4:

<div class="container">
    <div class="row">
        <h3>添加用户</h3>
        {% csrf_token %}
        {% for field in form %}
            <div>
                <label for="id_{{ field.name }}">{{ field.label }} : </label>
                {{ field }} <span>{{ field.errors.0 }}</span>

            </div>
        {% endfor %}
        <button class="btn btn-info" id="btn_add">提交</button>
    </div>

</div>

 

方式三:

<!--    方式3 -->

<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h3>新增员工</h3>
            <form action="" method="POST" novalidate>
                {% csrf_token %}
                <div class="form-group {% if form.name.errors.0 %}has-error{% endif %}">

                    <label for="id_{{ form.name.name }}">{{ form.name.label }}</label>
                    {{ form.name }} <span class="help-block">{{ form.name.errors.0 }}</span>
                </div>
                <div class="form-group {% if form.age.errors.0 %}has-error{% endif %} ">
                    <label for="id_{{ form.age.name }}">{{ form.age.label }}</label>
                    {{ form.age }} <span class="help-block">{{ form.age.errors.0 }}</span>
                </div>
                <div class="form-group {% if form.salary.errors.0 %}has-error{% endif %}">
                    <label for="id_salary">工资</label>
                    {{ form.salary }} <span class="help-block">{{ form.salary.errors.0 }}</span>
                </div>
                <div class="form-group {% if form.r_salary.errors.0 %}has-error{% endif %}">
                    <label for="id_r_salary">{{ form.r_salary.label }}</label>
                    {{ form.r_salary }} <span class="help-block">{{ form.r_salary.errors.0 }} {{ clean_errors.0 }}</span>
                </div>
                <input type="submit">

            </form>
        </div>
    </div>
</div>
</body>
</html>

视图函数中的代码:

from django.shortcuts import render, HttpResponse
from django.shortcuts import render
from app01.My_Forms import EmpForm
from app01 import models
# Create your views here.


def add_emp(request):
    if request.method == "GET":
        form = EmpForm()
        return render(request, "add_emp.html", {"form": form})

    else:

        form = EmpForm(request.POST)
        if form.is_valid():  # 进行数据校验
            # 校验成功
            data = form.cleaned_data  # 校验成功的值,会放在cleaned_data里。
            print(data)
            data.pop('r_salary')
            print(data)
            # {'name': 'alex', 'age': 28, 'salary': Decimal('11')}
            models.Emp.objects.create(**data)
            return HttpResponse("ok")
        else:
            print(form.errors) # 打印错误的信息
            # print(111)
            # return HttpResponse("aaa")
            clean_errors = form.errors.get("__all__")
            return render(request, "add_emp.html", {"form": form, "clean_errors": clean_errors})
小结:在有全局钩子的时候,出错的时候需要将全局钩子出错的clean_errors 传入到后端中填充页面,就行显示。一般的错误传入form对象即可。

 

2.常用字段定义

#          Django Form组件的使用
from django import forms
from django.forms import widgets
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError


class RegForm(forms.Form):
    name = forms.CharField(
        # 校验规则相关
        max_length=16,
        label="用户名",
        error_messages={
            "required": "该字段不能为空",
        },
        # widget控制的是生成html代码相关的
        widget=widgets.TextInput(attrs={"class": "form-control"})
    )
    pwd = forms.CharField(
        label="密码",
        min_length=6,
        max_length=10,
        widget=widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),
        error_messages={
            "min_length": "密码不能少于6位!",
            "max_length": "密码最长10位!",
            "required": "该字段不能为空",
        }
    )
    re_pwd = forms.CharField(
        label="确认密码",
        min_length=6,
        max_length=10,
        widget=widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),
        error_messages={
            "min_length": "密码不能少于6位!",
            "max_length": "密码最长10位!",
            "required": "该字段不能为空",
        }
    )

    email = forms.EmailField(
        label="邮箱",

        widget=widgets.EmailInput(attrs={"class": "form-control"}),
        error_messages={
            "required": "该字段不能为空",
        }
    )
    mobile = forms.CharField(
        label="手机",
        # 自己定制校验规则
        validators=[
            RegexValidator(r'^[0-9]+$', '手机号必须是数字'),
            RegexValidator(r'^1[3-9][0-9]{9}$', '手机格式有误')
        ],
        widget=widgets.TextInput(attrs={"class": "form-control"}),
        error_messages={
            "required": "该字段不能为空",
        }
    )

    city = forms.ChoiceField(
        choices=models.City.objects.all().values_list("id", "name"),
        label="城市",
        initial=1,
        widget=forms.widgets.Select
    )

    # 重写父类的init方法
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["city"].widget.choices = models.City.objects.all().values_list("id", "name")


    def clean_name(self):
        value = self.cleaned_data.get("name")
        if "金 瓶 梅" in value:
            raise ValidationError("不符合社会主义核心价值观!")
        return value

    # 重写父类的clean方法
    def clean(self):
        # 此时 通过检验的字段的数据都保存在 self.cleaned_data
        pwd = self.cleaned_data.get("pwd")
        re_pwd = self.cleaned_data.get("re_pwd")
        if pwd != re_pwd:
            self.add_error("re_pwd", ValidationError("两次密码不一致"))
            raise ValidationError("两次密码不一致")
        return self.cleaned_data
    # gender = forms.ChoiceField(
    #     choices=((1, "男"), (2, "女"), (3, "保密")),
    #     label="性别",
    #     initial=1,
    #     widget=forms.widgets.RadioSelect
    # )
    # hobby = forms.ChoiceField(
    #     choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    #     label="爱好",
    #     initial=3,
    #     widget=forms.widgets.Select
    # )
    # hobby2 = forms.MultipleChoiceField(
    #     choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    #     label="爱好",
    #     initial=[1, 3],
    #     widget=forms.widgets.SelectMultiple()
    # )
    #
    # keep = forms.ChoiceField(
    #     label="是否记住密码",
    #     initial="checked",
    #     widget=forms.widgets.CheckboxInput
    # )
    # hobby3 = forms.MultipleChoiceField(
    #     choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    #     label="爱好",
    #     initial=[1, 3],
    #
    #     widget=forms.widgets.CheckboxSelectMultiple(attrs={"class": "c1"})
    # )

 

其中如果在前端的页面中需要去选择下拉列表的时候:

  city = forms.ChoiceField(
        choices=models.City.objects.all().values_list("id", "name"),
        label="城市",
        initial=1,
        widget=forms.widgets.Select
    )

    # 重写父类的init方法
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["city"].widget.choices = models.City.objects.all().values_list("id", "name")

 3.使用ajax请求就行form表单的用户注册校验

add_user.html中的代码:

<div class="container">
    <div class="row">
        <h3>添加用户</h3>
        {% csrf_token %}
        {% for field in form %}
            <div>
                <label for="id_{{ field.name }}">{{ field.label }} : </label>
                {{ field }} <span>{{ field.errors.0 }}</span>

            </div>
        {% endfor %}
        <button class="btn btn-info" id="btn_add">提交</button>
    </div>

</div>


<script src="/static/js/jquery.js"></script>
<script>

    $("#btn_add").click(function () {
        let username = $("#id_username").val();
        let password = $("#id_password").val();
        $.ajax({
            url: "",
            type: "post",
            data: {
                username: username,
                password: password,
                csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),
            },
            success: function (ret) {
                {#console.log(ret);#}
                if (ret.status) {
                    location.href = "/login/"
                } else {
                    {#console.log(ret.msg);#}
                    $('span').html(""); // 清空页面之前的错误信息
                    $.each(ret.msg, function (i, j) {
                        console.log(i, j);
                        $("#id_" + i).next().text(j[0])
                    })
                }
            }
        })
    })


</script>

 

视图函数中函数 add_user代码:

def add_user(request):
    if request.method == "GET":
        form = UserForm()  # 初始化form对象
        return render(request, "add_user.html", {'form': form})

    if request.is_ajax():
        ret = {'status': 1, "msg": None}
        print(request.POST)
        form = UserForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data)

            # return redirect("/login/")
        else:
            print(form.errors)
            ret['status'] = 0
            ret['msg'] = form.errors
        return JsonResponse(ret)

 

定义的form 组件类的类代码:My_Form.py中的代码:

from django import forms


class UserForm(forms.Form):
    username = forms.CharField(min_length=4, label="用户名", widget=forms.widgets.TextInput(attrs={"class": "form-control"}))
    password = forms.CharField(min_length=6, label="密 码", widget=forms.widgets.PasswordInput(attrs={"class": "form-control", }))

即是查询其他的数据库就行一个显示,注意的是需要重写父类的方法,不然需要重启服务器。

参考:李文综老师博客:https://www.cnblogs.com/liwenzhou/p/8747872.html

 

转载于:https://www.cnblogs.com/longerandergou/p/11235389.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值