zoukankan      html  css  js  c++  java
  • 博客园项目总结

    一.在urls中写路由
    
    
    
    二.返回登录页面(login.html中写前端代码) 
    
    - username(用户名)
    
    - password(密码)
    
    - validCode(验证码)
    -submit(提交按钮)
    
    
    -submit
        -前端:显示的验证码图片
        <div class="col-md-6">
             <img class="validCode_img" src="/get_validCode_img/" alt="" width="200px" height="50px">
        </div>
     
        
      
    
    
    -后端:
      方式一:以二进制打开一个图片路径,获取内容 返回给前端
        import os
        path=os.path.join(settings.BASE_DIR,"blog","static","img","egon.jpg")
                     
        with open(path,"rb",)as f:
        data = f.read()
      
    
    方式二:导入Image,还是以二进制打开一个图片路径,获取内容,返回给前端
      from PIL import Image
        img=Image.new(mode="RGB",size=(120,40),color="blue")
                         
        f = open("validCode.png","wb")
        img.save(f,"png")
                         
        with open("validCode.png","rb") as f:
          data = f.read()
      
    
    方式三:
      from io import BytesIO  //导入文件句柄的对象和Image
                         
      from PIL import Image 
      img = Image.new(mode="RGB",size=(120,40),color="yellow")  //创建一个img图片的对象
      f=BytesIO()   //创建一个内存句柄的对象
      img.save(f,"png")
      data = f.getvalue()
      
    
    
    方式四: //创建一个img对象,获取一个画笔,创建字体font。定义一个列表,用for循环随机取出数字或者字母
      from io import BytesIO
        import random
     
        from PIL import Image,ImageDraw,ImageFont
        img = Image.new(mode="RGB",size=(120,40),color=(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
     
        draw = ImageDraw.Draw(img,"RGB") #获取一个画笔
        font = ImageFont.truetype("blog/static/font/kumo.ttf",28)
     
        valid_list = []
        for i in range(4):
            random_num = str(random.randint(0,9))
            random_lower_zimu = chr(random.randint(65,90))
            random_upper_zimu = chr(random.randint(97,122))
     
            random_char = random.choice([random_num,random_lower_zimu,random_upper_zimu])
     
            draw.text([4+i*24,10],random_char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font)
     
            valid_list.append(random_char)
     
        f=BytesIO()  //拿到一个句柄对象
        img.save(f,"png")  //用什么格式保存该图片
        data = f.getvalue()
     
        valid_str ="".join(valid_list)
        print(valid_str)
     
        request.session["keepValidCode"]=valid_str
        return HttpResponse(data)
     
     
      def index(request):
     
        return render(request,"index.html")
                         
      返回验证码并且把验证码写入session
      三.点击submit提交
    
      -ajax向后端提交 
    
        前端:(login.html.)
    
    
    <script>
        $("#subBtn").click(function () {
            $.ajax({
                url: "/login/",
                type: "POST",
                data: {
                    "username": $("#username").val(),
                    "password": $("#password").val(),
                    "validCode": $("#validCode").val(),
                    "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
                },
                success: function (data) {
                    console.log(data);
     
                    var response = JSON.parse(data);
                    if (response["is_login"]) {
                        location.href = "/index/"
                    }
                    else {
                        $(".error").html(response["error_msg"]).css("color", "red")
                    }
     
                }
            })
        })
     
    </script>
      后端:(在views中:)
    
    
    -判断是否是ajax请求
      if request.is_ajax():
    - 获取用户名 密码 验证码
        -username = request.POST.get("username")
        -password = reuqest.POST.get("password")
        -validCode = request.POST.get("validCode")
                     
        -判断验证用户信息是否存在
        -login_response = {"is_login":False,"error_msg":None}  
                         
        - 前端获取到的验证码和后端session的验证码是否相同
            如果相同:
              用户名和密码和数据库中是否匹配
            如果不同:
              obj[error_msg] = "username or password error"
            返回前端
    
    if validCode.upper() == request.session.get("keepValidCode").upper():
        user = auth.authenticate(username=username, password=password)
     
        if user:
            login_response["is_login"] = True
            auth.login(request, user)
     
        else:
            login_response["error_msg"] = "username or password error"
     
    else:
        login_response["error_msg"] = "validCode error"
     
    import json
     
    return HttpResponse(json.dumps(login_response))
     
    return render(request, "login.html")
    2.注册
        - urls
     
        -前端页面中写 username ,password,password,email,头像
         
         
        -form组件创建注册页面
            -widget的作用是,如果不加widget生成的前端标签是原生的input框,加上之后会变成渲染之后的
            -eg:username,password,repeat_pwd,email
                class RegForm(forms.Form):
                    email = forms.EmailField(widget=widgets.EmailInput(
                        attrs={"class": "form-control", "placeholder": "email"}
                    ))
                ....还有username,password,repeat_pwd
                如果form中有这些字段,则可以在前端页面中{{form_obj.username}},{{form_obj.password}}这样的方式取到值
                 
            -验证每个字段
                - clean_username(self):(用到了局部钩子)
                    cleaned_data它代表的是一个字典
                    -ret=models.UserInfo.objects.filter(username=self.cleaned_data.get("username"))
                     
                        if not ret:  #校验字段
                            return self.cleaned_data.get("username")
                        else:
                            raise ValidationError("用户名已注册")
                        -检查数据库中是否有username
                        -如果没有,验证的那个字段,如果有这个username,则返回cleaned_data取到的值,如果已经存在该用户,就走ValidationError,显示error信息
                         
                                     
                - clean_password(self):(用到了局部钩子)
                 
                    -同上方法验证,但需要注意,这个判断密码不能全是数字
                     
                def clean_validCode(self):(用到全局钩子)
     
                 
        -前端注册页面
            -上一步在后端上传的form对象渲染了username,password,email
             
            -生成头像
                -<img src="/static/img/default.png" alt="" id="avatar_img">
                -<input type="file" class="form-control" id="avatar_file">
                (生成一个默认的灰色框头像,如用户点击上传头像,此时应该吧图片遮到上传的文件上面,
                这里还有让parent设置成相对定位,children设置绝对定位,还有一点,应该不让灰色框隐藏,
                而是让他的透明度为0)
             
            -头像预览
                -找到头像标签,用到change事件,用一个变量去接受当前拿到的文件,然后对去到该文件的路径,让他付给this.result
             
                    $("#avatar_file").change(function () {
     
                    var ele_file=$(this)[0].files[0];  //拿到当前点击的文件
                    var reader=new FileReader();      //创建一个新对象
                    reader.readAsDataURL(ele_file);  
                    reader.onload=function (){
                        $("#avatar_img")[0].src=this.result
                    }
                    });
     
             
            - Ajax提交数据
                -使用formdata是因为里面有二进制文件
                - 上传二进制文件引入 FormData()
                - FormData()对象追加键值对
                    -$("#avatar_file")[0].files[0]) # jquery转DOM对象,取files对象最近一次上传的文件
                     
                    $.ajax({
                    url:"/reg/",
                    type:"POST",
                    data:formdata,
                    contentType:false,
                    processData:false,
                    headers:{"X-CSRFToken":$.cookie('csrftoken')},  //为了避免Forbedent禁止
                    success:function (data) {
                        console.log(data);
                        var data=JSON.parse(data);
     
                        //能拿到user代表注册成功,跳转到登录页面
                        if (data.user){
                            location.href="/login/"
                        }
                         
                        //反之
                         
                        else{
                        console.log(data.errorsList);
     
     
                        $.each(data.errorsList,function (i,j) {
                            console.log(i,j);
     
                            $span=$("<span>");
                            $span.addClass("pull-right").css("color","red");
                            $span.html(j[0]);
                            $("#id_"+i).after($span).parent().addClass("has-error");
     
                            if (i=="__all__"){
                                $("#id_repeat_pwd").after($span)
                            }
                        })
                    }
                     
                        注释:i为出错form组件字段、j为报错
                            each循环报错信息、新建span标签,给其增加样式(右漂浮,红色)
                            span的内容为报错信息
                            给出错的input标签后边添加span标签,并使其父级标签has-error
                            如果i使__all__:将报错添加到重新输入密码后边的span中
         
                     
                     
                 
        -后端注册(views中)  
            -判断是否是is_ajax请求
            -接收从前端提交过来的数据
            -form验证
                实例化对象,然后进行校验,将校验的结果和数据库进行匹配验证,获取校验结果,cleaned_data是一个字典的形式,
                如果校验失败,则走errors错误信息的列表
             
                 
                 form_obj=forms.RegForm(request.POST)  #接收从前端提交来的数据,规则和数据放在一起
                 
                if form_obj.is_valid():(开始校验,并获取校验结果)
                    username = form_obj.cleaned_data["username"]
                    password = form_obj.cleaned_data["password"]
                    email = form_obj.cleaned_data.get("email")
                    avatar_img = request.FILES.get("avatar_img")
                    ................
     
            -setting.py 如果只在这里设置 不在前端设置 用户接收不到文件
                    MEDIA_ROOT=os.path.join(BASE_DIR,"app01","media")
                    MEDIA_URL="/media/"
     
     
            -urls.py
                    # media 配置
                    from django.views.static import serve
                    from blog import  settings
                    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
    

      

  • 相关阅读:
    Hibernate 补充 ManyToOne、OneToMany、OneToOne的使用例
    Lint found fatal errors while assembling a release target
    5、jeecg 笔记之 minidao 条件判断
    4、jeecg 笔记之 自定义显示按钮 (exp 属性)
    restful api
    我学不动了...
    6、Flutter Error waiting for a debug connection: ProcessException: adb did not report f(转)
    5、Flutter 实现 ViewPager、bottomNavigationBar 界面切换
    4、Flutter 采坑记录篇二_依赖库不兼容
    3、Finished with error: FormatException: Bad UTF-8 encoding 0xc3 (at offset 169)
  • 原文地址:https://www.cnblogs.com/liuchengdong/p/7892276.html
Copyright © 2011-2022 走看看