基于Django Form表单组件与AJAX的注册程序

下面的代码是老男孩课程基于Form组件和AJAX以及Django的auth组件的注册程序。

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎注册</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form novalidate action="/reg/" method="post" class="form-horizontal reg-form" enctype="multipart/form-data">
                {% csrf_token %}

                <div class="form-group">
                    <label for="{{ form_obj.username.id_for_label }}"
                           class="col-sm-2 control-label">{{ form_obj.username.label }}</label>
                    <div class="col-sm-8">
                        {{ form_obj.username }}
                        <span class="help-block">{{ form_obj.username.errors.0 }}</span>
                    </div>
                </div>

                <div class="form-group">
                    <label for="{{ form_obj.password.id_for_label }}"
                           class="col-sm-2 control-label">{{ form_obj.password.label }}</label>
                    <div class="col-sm-8">
                        {{ form_obj.password }}
                        <span class="help-block">{{ form_obj.password.errors.0 }}</span>
                    </div>
                </div>

                <div class="form-group">
                    <label for="{{ form_obj.re_password.id_for_label }}"
                           class="col-sm-2 control-label">{{ form_obj.re_password.label }}</label>
                    <div class="col-sm-8">
                        {{ form_obj.re_password }}
                        <span class="help-block">{{ form_obj.re_password.errors.0 }}</span>
                    </div>
                </div>

                <div class="form-group">
                    <label for="{{ form_obj.email.id_for_label }}"
                           class="col-sm-2 control-label">{{ form_obj.email.label }}</label>
                    <div class="col-sm-8">
                        {{ form_obj.email }}
                        <span class="help-block">{{ form_obj.email.errors.0 }}</span>
                    </div>
                </div>

                <div class="form-group">
                    <label
                            class="col-sm-2 control-label">头像</label>
                    <div class="col-sm-8">
                        <label for="id_avatar"><img id="avatar-img" src="/static/img/default.png" alt=""></label>
                        <input accept="image/*" type="file" name="avatar" id="id_avatar" style="display: none">
                        <span class="help-block"></span>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type="button" class="btn btn-success" id="reg-submit">注册</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>


<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
    // 找到头像的input标签绑定change事件
    $("#id_avatar").change(function () {
        // 1. 创建一个读取文件的对象
        var fileReader = new FileReader();
        // 取到当前选中的头像文件
        // console.log(this.files[0]);
        // 读取你选中的那个文件
        fileReader.readAsDataURL(this.files[0]);  // 读取文件是需要时间的
        fileReader.onload = function () {
            // 2. 等上一步读完文件之后才 把图片加载到img标签中
            $("#avatar-img").attr("src", fileReader.result);
        };
    });
    // AJAX提交注册的数据
    $("#reg-submit").click(function () {
        // 取到用户填写的注册数据,向后端发送AJAX请求
        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("email", $("#id_email").val());
        formData.append("avatar", $("#id_avatar")[0].files[0]);
        formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());

        $.ajax({
            url: "/reg/",
            type: "post",
            processData: false,
            contentType: false,
            data : formData,
            success:function (data) {
                if (data.status){
                    // 有错误就展示错误
                    // console.log(data.msg);
                    // 将报错信息填写到页面上
                    $.each(data.msg, function (k,v) {
                        // console.log("id_"+k, v[0]);
                        // console.log($("#id_"+k));
                        $("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error");
                    })

                }else {
                    // 没有错误就跳转到指定页面
                    location.href = data.msg;
                }
            }
        })
    });

    // 将所有的input框绑定获取焦点的事件,将所有的错误信息清空
    $("form input").focus(function () {
        $(this).next().text("").parent().parent().removeClass("has-error");
    })
</script>
</body>
</html>

forms.py

"""
bbs用到的form类
"""

from django import forms
from django.core.exceptions import ValidationError

# 定义一个注册的form类
class RegForm(forms.Form):
    username = forms.CharField(
        max_length=16,
        label="用户名",
        error_messages={
            "max_length": "用户名最长16位",
            "required": "用户名不能为空",
        },
        #通过表单的widgets属性可以设置生辰的HTML代码的CSS样式,widgets还有其他的用途。
        widget=forms.widgets.TextInput(
            attrs={"class": "form-control"},
        )
    )

    password = forms.CharField(
        min_length=6,
        label="密码",
        widget=forms.widgets.PasswordInput(
            attrs={"class": "form-control"},
            render_value=True,
        ),
        error_messages={
            "min_length": "密码至少要6位!",
            "required": "密码不能为空",
        }
    )

    re_password = forms.CharField(
        min_length=6,
        label="确认密码",
        widget=forms.widgets.PasswordInput(
            attrs={"class": "form-control"},
            render_value=True,
        ),
        error_messages={
            "min_length": "确认密码至少要6位!",
            "required": "确认密码不能为空",
        }
    )

    email = forms.EmailField(
        label="邮箱",
        widget=forms.widgets.EmailInput(
            attrs={"class": "form-control"},

        ),
        error_messages={
            "invalid": "邮箱格式不正确!",
            "required": "邮箱不能为空",
        }
    )


    # 重写全局的钩子函数,对确认密码做校验
    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

views.py

def register(request):
    #如果表单提交用的是 POST 请求,那么该视图将创建一个表单实例并使用请求中的数据填充它: form = NameForm(request.POST) 这叫“绑定数据到表单” 
    if request.method == "POST":
        ret = {"status": 0, "msg": ""}
        form_obj = forms.RegForm(request.POST)
        print(request.POST)
        # 帮我做校验
        # Form表单的实例含有is_valid()方法,这个方法会对传进forms对象的数据进行校验,如果所有数据都符合要求,那么该方法会返回True,然后把表单数据放到cleaned_data中,cleaned_data会字典形式的数据。
        if form_obj.is_valid():
            # 校验通过,去数据库创建一个新的用户
            form_obj.cleaned_data.pop("re_password")
            avatar_img = request.FILES.get("avatar")
            models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img)
            ret["msg"] = "/index/"
            return JsonResponse(ret)
        else:
            print(form_obj.errors)
            ret["status"] = 1
            ret["msg"] = form_obj.errors
            print(ret)
            print("=" * 120)
            return JsonResponse(ret)
    # 生成一个form对象
    #如果是get方式请求,则直接返回form表单
    form_obj = forms.RegForm()
    print(form_obj.fields)
    return render(request, "register.html", {"form_obj": form_obj})

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Django中自定义的表单多级联动,需要使用到`ModelForm`和JavaScript来实现。 首先,我们需要创建一个ModelForm,用于实现表单的自定义字段和验证规则。 ```python from django import forms from .models import ModelA, ModelB class MyForm(forms.ModelForm): class Meta: model = ModelA fields = '__all__' # 可根据实际需求选择需要的字段 def __init__(self, *args, **kwargs): super(MyForm, self).__init__(*args, **kwargs) self.fields['second_model'] = forms.ModelChoiceField(queryset=ModelB.objects.none()) if 'first_model' in self.data: try: first_model_id = int(self.data.get('first_model')) self.fields['second_model'].queryset = ModelB.objects.filter(first_model_id=first_model_id) except (ValueError, TypeError): pass elif self.instance.pk: self.fields['second_model'].queryset = self.instance.first_model.modelb_set.order_by('name') ``` 在上面的例子中,`ModelA`是第一个模型,`ModelB`是第二个模型。在`MyForm`类的初始化方法中,根据`first_model`字段的值动态更新`second_model`字段的queryset,实现了多级联动。 接下来,我们需要在模板中添加HTML和JavaScript来实现多级联动效果。 ```html <form method="POST" action=""> {% csrf_token %} {{ form.as_p }} <button type="submit">Submit</button> </form> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script> $(document).ready(function() { $('#id_first_model').change(function() { var url = $(this).attr('data-href'); var first_model_id = $(this).val(); $.ajax({ url: url, data: { 'first_model_id': first_model_id }, success: function(data) { $('#id_second_model').html(data); } }); }); }); </script> ``` 在上面的例子中,我们使用了jQuery来监听`first_model`字段的变化事件。当`first_model`字段的值发生改变时,执行AJAX请求,获取到对应`second_model`字段的选项,并更新页面上的`second_model`字段。 总结来说,我们通过自定义的表单类`MyForm`来实现外键的多级联动,然后通过JavaScript的AJAX请求和动态更新页面的选项来实现表单的多级联动效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值