forms

# 创建注册form类
class RegForm(forms.Form):
    #创建注册用户字段
    username = forms.CharField(
        label='用户名',
        max_length=16,
        min_length=4,
        error_messages={
            "max_length":"用户名最长不能超过16位",
            "min_length": "用户名最短不能少于4位",
            "required":"用户名不能为空",
        },
        widget=forms.widgets.TextInput(attrs={"class":"form-control"})
    )
    #创建注册密码字段
    password = forms.CharField(
        label='密码',
        max_length=16,
        min_length=6,
        error_messages={
            "max_length":"密码最长不能超过16位",
            "min_length": "密码最短不能少于6位",
            "required":"密码不能为空",
        },
        widget=forms.widgets.PasswordInput(attrs={"class":"form-control"})
    )

    #创建确认密码字段
    re_password = forms.CharField(
        label='确认密码',
        max_length=16,
        min_length=6,
        error_messages={
            "max_length":"确认密码最长不能超过16位",
            "min_length": "确认密码最短不能少于6位",
            "required":"确认密码不能为空",
        },
        widget=forms.widgets.PasswordInput(attrs={"class":"form-control"})
    )

    #创建手机号字段
    phone=forms.CharField(
        max_length=11,
        min_length=11,
        label="手机号码",
        validators=[
            RegexValidator(r'^\d{11}$', "手机号必须是11位数字"),
            RegexValidator(r'^1[356789][0-9]{9}$', "手机号码格式不正确")
        ],
        error_messages={
            "max_length": "手机号长度为11位",
            "min_length": "手机号长度为11位",
            "required": "手机号不能为空",
        },
        widget=forms.widgets.TextInput(attrs={"class": "form-control"})
    )

    #局部钩子
    def clean_username(self):
        #去除username的值
        value=self.cleaned_data.get("username")
        if 'JPM' in value:  #判断是否包含,包含就返回错误
            raise ValidationError("不符合社会主义核心价值观!")
        elif models.UserInfo.objects.filter(username=value): #判断是否能搜索到 能就返回错误信息
            raise ValidationError("用户名重复!")
        else:
            return value #无错返回原值

    #局部钩子
    def clean_phone(self):
        #去除username的值
        value=self.cleaned_data.get("phone")
        if models.UserInfo.objects.filter(phone=value): #判断是否能搜索到 能就返回错误信息
            raise ValidationError("手机号重复!")
        else:
            return value #无错返回原值

    #全局钩子,一般用于需要调用多个参数时,比如调用密码和确认密码
    def clean(self):
        #取密码
        pwd=self.cleaned_data.get("password")
        re_pwd=self.cleaned_data.get("re_password")

        #做比较
        #判断re_pwd 或 pwd有没有空 有的话直接跳错误,没有的再拿pwd和re_pwd比较
        if re_pwd and pwd ==re_pwd:
            #无错返回数据
            return self.cleaned_data
        else:
            #有错返回异常
            self.add_error("re_password","两次输入的密码不一样")
            raise ValidationError("两次输入的密码不一样")

———————————————————————————————————————————————————————————————————————————————

 url

 

from django.conf.urls import url
from django.contrib import admin
from bolg import  views
from django.views.static import serve
from django.conf import settings


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    #主界面
    url(r'^$', views.index),
    #登录
    url(r'^login/', views.login),
    #生成图片
    url(r'^v_code/', views.v_code),
    #主界面
    url(r'^index/', views.index),
    #注册
    url(r'^reg/', views.reg),
    #注销
    url(r'^zhuxiao/', views.zhuxiao),
    #查询media路径下的
    url(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT})

]

———————————————————————————————————————————————————————————————————————————————

 views

# 注册界面
def reg(request):
    reg_obj = forms.RegForm()
    if request.method == "POST":
        # 加判断
        ret = {'code': 0}
        # 传值创建对象
        reg_obj = forms.RegForm(request.POST)
        # 用is_valid验证数据有没有问题
        if reg_obj.is_valid():
            # 取出头像图片文件
            avatar_obj = request.FILES.get('avatar')
            # 把数据re_password取出,因为表中没有re_password这个字段,只是用来验证
            reg_obj.cleaned_data.pop('re_password')
            # 创建添加用户
            models.UserInfo.objects.create_user(
                # 添加字段对应的值
                avatar=avatar_obj,
                # 打散字典,值已被cleaned_data转成字符串
                **reg_obj.cleaned_data
            )
            ret['data'] = '/index/'
        else:
            ret['code'] = 1
            # 把reg_obj返回的错误数据放入
            ret['data'] = reg_obj.errors
        return JsonResponse(ret)

    return render(request, 'reg.html', {'reg_obj': reg_obj})

#注销
#用 auth.logout(request) 将当前请求的session信息会全部清除
def zhuxiao(request):
    auth.logout(request)

    return redirect('/index/')

#主界面
def index(request):
    #is_authenticated判断是否以登录,登录时必须在login存参数,否则无法生效
    if request.user.is_authenticated():
        #取出用户名
        usernmae=request.user.username
        #根据用户名拿对象
        user_obj=models.UserInfo.objects.filter(username=usernmae)
        #把对象传递进去
        return render(request, 'index.html',{"user_obj":user_obj})

    return render(request, 'index.html',{"user_obj":''})

———————————————————————————————————————————————————————————————————————————————

 html-reg

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册界面</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <style>
        #img_tou {
            width: 80px;
            height: 80px;
        }
        #ding{
            margin-top: 120px;
        }

    </style>

</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3 "id="ding">
            {#            面板开始#}

            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">BBS注册界面</h3>
                </div>
                <div class="panel-body">
                    {#                    注册界面开始#}

                    <form class="form-horizontal" autocomplete="off" novalidate>
                        <div class="form-group">
                            <label for="{{ reg_obj.username.id_for_label }}"
                                   class="col-sm-2 control-label">{{ reg_obj.username.label }}</label>
                            <div class="col-sm-10">
                                {{ reg_obj.username }}
                                <span class="help-block"></span>

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

                            </div>
                        </div>
                        <div class="form-group">
                            <label for="{{ reg_obj.re_password.id_for_label }}"
                                   class="col-sm-2 control-label">{{ reg_obj.re_password.label }}</label>
                            <div class="col-sm-10">
                                {{ reg_obj.re_password }}
                                <span class="help-block"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="{{ reg_obj.phone.id_for_label }}"
                                   class="col-sm-2 control-label">{{ reg_obj.phone.label }}</label>
                            <div class="col-sm-10">
                                {{ reg_obj.phone }}
                                <span class="help-block"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for=""
                                   class="col-sm-2 control-label">头像</label>
                            <div class="col-sm-10">
                                <input accept="image/*" type="file" id="touxiang" name="avatar" style="display: none">
                                <label for="touxiang"><img id="img_tou" src="/static/img/default.png" alt=""></label>
                            </div>
                        </div>

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

                    {#                    注册界面结束#}

                </div>
            </div>

            {#            面板结束#}

        </div>
    </div>

</div>

<script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
<script src="/static/setupAjax.js"></script>

<script>

    $('#zhuche').click(function () {
        //创建表单对象
        var data_obj = new FormData();
        //把上面用户输入的所有值都添加进去
        data_obj.append("username", $('#id_username').val());
        data_obj.append("password", $('#id_password').val());
        data_obj.append("phone", $('#id_phone').val());
        data_obj.append("re_password", $('#id_re_password').val());
        data_obj.append("avatar", $('#touxiang')[0].files[0]);

        $.ajax({
            url: "/reg/",
            type: 'post',
            processData: false,
            contentType: false,
            data: data_obj,
            success: function (data) {
                if (data.code) {
                    //创建变量接收错误信息
                    var cuowu = data.data;
                    //用each方法取出所有的k,v
                    $.each(cuowu, function (k, v) {
                        // k: 字段名  v:报错信息的数组
                        // 根据字段名找对应的input标签,把错误信息添加到对应位置
                        //遍历.help-block类,将值改成对应的v,然后再找关系颜色的那个类,将其改为警告红色
                        $("#id_" + k).next(".help-block").text(v[0]).parent().parent().addClass("has-error");
                    })
                } else {
                    location.href = data.data || "/login/"
                }
            }
        })
    });
    //找到form 下的input框 加点击事件,点击后用next找到span标签,修改其text值,删除警告色
    $('form input').click(function () {
        $(this).next(".help-block").text("").parent().parent().removeClass("has-error");
    });

    $('#touxiang').change(function () {
        // 找到你选中的那个头像文件
        var fileObj = this.files[0];
        // 读取文件路径
        var fileReader = new FileReader();
        fileReader.readAsDataURL(fileObj);
        // 等图片被读取完毕之后,再做后续操作
        fileReader.onload = function () {
            // 设置预览图片
            $("#img_tou").attr("src", fileReader.result);
        };
    })


</script>

</body>
</html>

———————————————————————————————————————————————————————————————————————————————

 html-index

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <style>
        #img_tou {
            width: 40px;
            height: 40px;
            margin-top: 5px;
        }

    </style>
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Brand</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">One more separated link</a></li>
                    </ul>
                </li>
            </ul>
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Search">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
{#            判断传来的是否有对象,有就调用对象里的值,没有就登录注册#}
                {% if user_obj %}
{#                    调用对象里的值进行操作#}
                    <li><img id="img_tou" src="/media/{{ request.user.avatar }}" alt=""></li>
                    <li><a href="#">{{ request.user.username }}</a></li>
                    <li><a href="/zhuxiao/">注销</a></li>
                {% else %}
                    <li><a href="/login/">登录</a></li>
                    <li><a href="/reg/">注册</a></li>
                {% endif %}
                {#                <li>{% if user_obj %}<a href="#">{{ user_obj.username }}</a>{% else %}<a href="/login/">登录</a>{% endif %}</li>#}
                {#                <li class="dropdown">#}
                {#                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"#}
                {#                       aria-expanded="false">Dropdown <span class="caret"></span></a>#}
                {#                    <ul class="dropdown-menu">#}
                {#                        <li><a href="#">Action</a></li>#}
                {#                        <li><a href="#">Another action</a></li>#}
                {#                        <li><a href="#">Something else here</a></li>#}
                {#                        <li role="separator" class="divider"></li>#}
                {#                        <li><a href="#">Separated link</a></li>#}
                {#                    </ul>#}
                {#                </li>#}

            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-2 ">
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
        </div>
        <div class="col-md-8 "></div>
        <div class="col-md-2 ">
            <div class="panel panel-info">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
        </div>

    </div>
</div>


<script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
<script src="/static/setupAjax.js"></script>



</body>
</html>

———————————————————————————————————————————————————————————————————————————————