zoukankan      html  css  js  c++  java
  • day 77 基于form组件的注册功能

    Form 表单 py文件

    from django  import  forms
    
    #定义一个form类注册用
    class RegForm (forms.Form):
        username =forms.CharField(
            max_length=16,
            label='用户名',
            error_messages={
                " max_length":"用户名长度最长为16位",
                'required':'用户名不能为空',
            },
            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':'邮箱不能为空',
            }
         )
    

      

    settings文件

    """
    Django settings for day77 project.
    
    Generated by 'django-admin startproject' using Django 1.11.12.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.11/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.11/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '@qbulznqai1k%twz$(m)76#ztkt6%^+k2airzl5-pt@lu2v)oz'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 'day77.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'day77.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    
    DATABASES = {
        # 'default': {
        #     'ENGINE': 'django.db.backends.sqlite3',
        #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # },
    
        'default':{
            'ENGINE':'django.db.backends.mysql',
            'NAME':'day77',
            'USER':'root',
            'PASSWORD':'123456',
            'HOST':'127.0.0.1',
            'PORT':3306,
    
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.11/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS=[
        os.path.join(BASE_DIR,'static')
    ]
    
    # 告诉Djanog 项目用哪张表做认证
    AUTH_USER_MODEL='app01.UserInfo'
    

      

    modules文件 

    from django.db import models
    
    # Create your models here.
    from django.contrib.auth.models import AbstractUser
    
    class UserInfo(AbstractUser):
        '''
        用户表
        '''
        nid  =models.AutoField(primary_key=True)
        phone  =models.CharField(max_length=11,null=True,unique=True)
        avatar = models.FileField(upload_to='avatars/',default='avatars/default.png',verbose_name='头像')
        create_time =models.DateTimeField(auto_now_add=True)
        blog =models.OneToOneField(to='Blog',to_field='nid',null=True)
        def __str__(self):
            return self.username
    
    class Blog(models.Model):
        '''
        博客信息
        '''
        nid =models.AutoField(primary_key=True)
        title =models.CharField(max_length=64)
        site =models.CharField(max_length=32,unique=True)
        theme =models.CharField(max_length=32)
    
        def __str__(self):
            return self.title
    #
    
    class  Category(models.Model):
        '''
        个人博客文章分类
        '''
        nid =models.AutoField(primary_key=True)
        title =models.CharField(max_length=32)#分类标题
        blog = models.ForeignKey(to ='Blog',to_field='nid')#外键关联博客,一个博客站点可以有多个分类
    
        def __str__(self):
            return self.title
    
    class Tag(models.Model):
        ''''
        标签
        '''
        nid =models.AutoField(primary_key=True)
        title =models.CharField(max_length=32)
        blog =models.ForeignKey(to='Blog',to_field='nid') #所属博客
    
        def __str__(self):
            return self.title
    
    class Article(models.Model):
        '''
        文章
        '''
        nid =models.AutoField(primary_key=True)
        title = models.CharField(max_length=50) #文章标题描述
        desc =models.CharField(max_length=255) #文章描述
        create_time =models.DateTimeField()#创建时间
    
        category = models.ForeignKey(to ='Category',to_field='nid',null=True)
        user = models.ForeignKey(to='UserInfo',to_field='nid')
        tags =models.ManyToManyField( # 中介模型
            to ='Tag',
            through='Article2Tag',
            through_fields=('article','tag')#注意顺序
    
        )
    
        def __str__(self):
            return self.title
    
    class ArticleDetail(models.Model):
        '''
        文章详情
        '''
        nid =models.AutoField(primary_key=True)
        content = models.TextField()
        article =models.OneToOneField(to ='Article',to_field='nid')
    
    class Article2Tag(models.Model):
        '''
        文章和标签的多对多关系表
        '''
        nid =models.AutoField(primary_key=True)
        article =models.ForeignKey(to='Article',to_field='nid')
        tag =models.ForeignKey(to ='Tag',to_field='nid')
    
        class Meta:
            unique_together = (('article','tag'),)
    
    class ArticleUpDown(models.Model):
        '''
        点赞
        '''
        nid= models.AutoField(primary_key=True)
        user =models.ForeignKey(to ='UserInfo',null=True)
        article = models.BooleanField(default=True)
    
        class  Meta:
            unique_together = (('article','user'),)
    
    class Comment(models.Model):
        '''
        评论表
        '''
        nid = models.AutoField(primary_key=True)
        article =models.ForeignKey(to ='Article',to_field='nid')
        user =models.ForeignKey(to ='UserInfo',to_field='nid')
        content =models.CharField(max_length=255)#评论内容
        create_time =models.DateTimeField(auto_now_add=True)
        parent_comment =models.ForeignKey('self',null=True)
    
        def __str__(self):
            return self.content
    

    views文件 

    from app01 import  form,models
    from django.db import models
    def reg(request):
        if request.method=='POST':
            ret={'status':0,'msg':''}
            form_obj =form.RegForm(request.POST)
            #帮我做校验
            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) return JsonResponse(form_obj.errors) # return render(request,'ret.html',{'form_obj': form_obj})
    #生成一个form对象
    form_obj = form.RegForm()
    print(form_obj)
    print("== "*120)
    return render(request,'reg.html',{'form_obj': form_obj})
    
    

      输入 web地址 

     

    前端代码 

    <!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 autocomplete="off" 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, // 告诉jQuery不要处理我的数据
    contentType: false, // 告诉jQuery不要设置content类型
    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");
    });

    // 给username input框绑定一个失去焦点的事件,失去焦点之后就校验用户名是否已被注册
    {#$("#id_username").blur(function () {#}
    $("#id_username").on("input", function () {
    // 取到用户填写的值
    var username = $(this).val();
    // 发请求
    $.ajax({
    url: "/check_username_exist/",
    type: "get",
    data: {"username": username},
    success: function (data) {
    if (data.status){
    // 用户名已被注册
    $("#id_username").next().text(data.msg).parent().parent().addClass("has-error");
    }
    }
    })
    })
    </script>
    </body>
    </html>

    密码输入错误的案例 

      

    打印结果

    传到前端的 代码 

    登录 views

    def logout(request):
        auth.logout(request)
        return redirect('/index/')
    
    
    def login(request):
        # if request.is_ajax():  # 如果是AJAX请求
        if request.method == "POST":
            # 初始化一个给AJAX返回的数据
            ret = {"status": 0, "msg": ""}
            # 从提交过来的数据中 取到用户名和密码
            username = request.POST.get("username")
            pwd = request.POST.get("password")
            # 获取极验 滑动验证码相关的参数
            gt = GeetestLib(pc_geetest_id, pc_geetest_key)
            challenge = request.POST.get(gt.FN_CHALLENGE, '')
            validate = request.POST.get(gt.FN_VALIDATE, '')
            seccode = request.POST.get(gt.FN_SECCODE, '')
            status = request.session[gt.GT_STATUS_SESSION_KEY]
            user_id = request.session["user_id"]
    
            if status:
                result = gt.success_validate(challenge, validate, seccode, user_id)
            else:
                result = gt.failback_validate(challenge, validate, seccode)
            if result:
                # 验证码正确
                # 利用auth模块做用户名和密码的校验
                user = auth.authenticate(username=username, password=pwd)
                if user:
                    # 用户名密码正确
                    # 给用户做登录
                    auth.login(request, user)  # 将登录用户赋值给 request.user
                    ret["msg"] = "/index/"
                else:
                    # 用户名密码错误
                    ret["status"] = 1
                    ret["msg"] = "用户名或密码错误!"
            else:
                ret["status"] = 1
                ret["msg"] = "验证码错误"
    
            return JsonResponse(ret)
        return render(request, "login.html")
    

      

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/mystyle.css">
    </head>
    <body>
    
    <nav class="navbar navbar-inverse">
        <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="#">The Blog</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>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    {% if request.user.username %}
                        <li><a href="#">{{ request.user.username }}</a></li>
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                               aria-expanded="false">个人中心<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="/logout/">注销</a></li>
                            </ul>
                        </li>
                    {% else %}
                        <li><a href="/login/">登录</a></li>
                        <li><a href="/reg/">注册</a></li>
                    {% endif %}
                </ul>
            </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
    </nav>
    
    <!-- 主页面 开始-->
    <div class="container">
        <div class="row">
            <div class="col-md-2">
                <div class="panel panel-primary">
                    <div class="panel-heading">左侧广告位一</div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
                <div class="panel panel-info">
                    <div class="panel-heading">左侧广告位二</div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
            </div>
            <div class="col-md-8">
                <!-- 文章列表 开始 -->
                <div class="article-list">
                    {% for article in article_list %}
                        <div class="article">
                            <h3><a href="">{{ article.title }}</a></h3>
                            <div class="media">
                                <div class="media-left">
                                    <a href="#">
                                        <img class="media-object author-img" src="/media/{{ article.user.avatar }}" alt="...">
                                    </a>
                                </div>
                                <div class="media-body">
                                    <p>{{ article.desc }}</p>
                                </div>
                            </div>
                            <div class="article-footer">
                                <span><a href="">{{ article.user.username }}</a></span>发布于
                                <span>{{ article.create_time|date:'Y-m-d H:i:s' }}</span>
                                <span class="glyphicon glyphicon-comment">评论({{ article.comment_count }})</span>
                                <span class="glyphicon glyphicon-thumbs-up">点赞({{ article.up_count }})</span>
                            </div>
                        </div>
                    {% endfor %}
    
                </div>
                <!-- 文章列表 结束-->
    
            </div>
            <div class="col-md-2">
                <div class="panel panel-primary">
                    <div class="panel-heading">右侧广告位一</div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
                <div class="panel panel-info">
                    <div class="panel-heading">右侧广告位二</div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- 主页面 结束-->
    
    <script src="/static/jquery-3.3.1.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    </body>
    </html>

    基于object查询 于基于queryset查询.

  • 相关阅读:
    spring项目(springmvc)(多模块/单模块)maven打包引入第三方jar方式,使用scope:system配置systemPath编译,不用添加到本地仓库!
    Mysql 执行效率 性能综合贴
    前端Js框架 UI框架汇总 特性 适用范围 选择
    通用 正则表达式 C# (.NET)Regex 总结
    VSCode Node cannot launch program setting the 'outFiles' attribute might help
    CSS常见问题,定位技巧总结
    java 欢迎页 主页 设置为servlet的方法
    MSSQL Server 及 MSSQL Express版本 自动备份
    SQL Server 2008 R2 安装 下载
    mysql 日期计算集合
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/9117641.html
Copyright © 2011-2022 走看看