• 博客论坛


    此文专门记录一些用到的新知识。

    一.Form组件验证登录:

    #Form表单定制验证码:
        code = fields.CharField(widget=widgets.TextInput(
                                attrs={'class': "form-control", 'placeholder': '验证码'}), )
    
    #将request一并传入,用来获取session,因此在使用Form组件时,实例化时要传request 
    #如 obj = RegForm(request,request.POST)   
    
        def __init__(self,request,*args,**kwargs):
            super().__init__(*args,**kwargs)
            self.request = request
        #自定义验证规则,验证用户输入的验证码是否正确
        def clean_code(self):
        #取到已经写入session的验证码'code'
            session_code = self.request.session.get('code')
    #与取到的用户输入值进行匹配,判断是否正确
            input_code = self.cleaned_data.get('code')
            if session_code == input_code:
                return input_code
            raise ValidationError('验证码错误')     
    
    
    #验证码视图函数
    from utils.random_check_code import rd_check_code
    from io import BytesIO
    from utils.FormInfo import LoginInfo,RegForm
    
    def check_code(request):
    #使用自定制的验证码生成函数,得到返回值为 img:验证码生成的图片,code:验证码生成的实际字符串
        img, code = rd_check_code()
    #打开内存写入验证码图片,BytesIO可以写入二进制文件
        stream = BytesIO()
        img.save(stream, 'png')
    #将生成的验证码字符串写入session便于Form组件的验证
        request.session['code'] = code
    #getvalue()方法可以获取写入的数据,即此函数发送的是生成的图片
        return HttpResponse(stream.getvalue())
    
    
    
    #实际应用:注册用户为例
    #后端代码:
    def reg(request):
        if request.method == 'GET':
    #即使GET时无需验证,但Form规定了要传一个request,所以这里也要传参
            obj = RegForm(request)
            return render(request,'sign.html',{'obj':obj})
    
        else:
    #传入request便于获取session验证
            obj = RegForm(request,request.POST)
            if not obj.is_valid():
                return render(request,'sign.html',{'obj':obj})
            else:
                obj.cleaned_data.pop('pwd_again')
                models.UserInfo.objects.create(**obj.cleaned_data)
                return redirect('/login.html')
    

     前端代码:

    <div class="form-group" style="margin-top: 60px">
        <label class="col-sm-2 control-label">验证码</label>
        <div class="col-sm-3">
                      {{ obj.code }}
        </div>
        <div class="col-sm-5">
            <!-- 验证码图片写上/check_code/,Django urls里再配置好指向处理验证码的函数,
    此时页面加载向check_code发请求,返回的就是生成好的图片达到生成验证码的效果 -->
                      <img style=" 120px;height: 30px;" src="/check_code/"         
                     id="img-code">
        </div>
        <span style="color: red"> {{ obj.errors.code.0 }}</span>
    </div>
    

      验证码生成函数代码:

    #需要安装PIL模块生成图片
    from PIL import Image,ImageDraw,ImageFont,ImageFilter
    import random
    
    #font_file指向字体文件路径:
    def rd_check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
        code = []
        img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
        draw = ImageDraw.Draw(img, mode='RGB')
     
        def rndChar():
            """
            生成随机字母   
            :return:
            """
            return chr(random.randint(65, 90))
     
        def rndColor():
            """
            生成随机颜色
            :return:
            """
            return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
     
        # 写文字
        font = ImageFont.truetype(font_file, font_size)
        for i in range(char_length):
            char = rndChar()
            code.append(char)
            h = random.randint(0, 4)
            draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
     
        # 写干扰点
        for i in range(10):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
     
        # 写干扰圆圈
        for i in range(10):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
            x = random.randint(0, width)
            y = random.randint(0, height)
            draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
     
        # 画干扰线
        for i in range(3):
            x1 = random.randint(0, width)
            y1 = random.randint(0, height)
            x2 = random.randint(0, width)
            y2 = random.randint(0, height)
     
            draw.line((x1, y1, x2, y2), fill=rndColor())
     
        img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    #返回值为图片以及验证码字符串 return img,''.join(code)
    clean()方法是其它全部的验证规则执行完毕才会执行,通常可以用来对多个字段之间进行共同验证,比如验证2次输入密码是否一致。    
    
    def clean(self):
            p1 = self.cleaned_data.get('password')
            p2 = self.cleaned_data.get('password2')
            if p1 == p2:
               #clean方法return的不是字段
                return None
        #同样的,添加错误是往None添加,在试图函数中通过obj.errors['__all__']取值,
    而在模版中则通过obj.errors.non_field_errors取值,此为常规写法。
            # self.add_error(None,ValidationError('密码不一致'))
    #当然,使用add_error函数可以往None里添加,自然也能往我们的字段中添加,
    即key,value中key改为我们的字段名,即模版中相对应也可以obj.errors.字段名来取。
            self.add_error("password2",ValidationError('密码不一致'))
    

      

      

    二.models应用:

    1.分组:

    #分类函数
    from django.db.models import Count,Min,Max,Sum
    #values里写以什么字段进行分组以及可以取到的字段,然后.annotate(别名=Count('聚合计算个数的字段,也可以直接写1'))
        cate_list = models.Article.objects.filter(blog__site=site).values('category__title','category__nid').annotate(c=Count('nid'))
        tags_list = models.Article.objects.filter(blog__site=site).values('tags__title','tags__nid').annotate(c=Count(1))
    
    #时间查询需要涉及到时间的格式化,额外的东西所以这里用到extar
        #mysql查询
        # data_time = models.Article.objects.extra(select={'c':'date_fomat(create_time,"%%Y-%%m")'}).values('c').annotate(ct=Count('nid'))
        #sqlite3查询
        date_list = models.Article.objects.filter(blog__site=site).extra(select={'c':'strftime("%%Y-%%m",create_time)'}).
            values('c').annotate(ct=Count('nid'))
    

      

  • 相关阅读:
    递归寻找子节点的所有父节点(父,爷,祖等)
    nodemon在VSCODE中 调试nodeJS的使用方法
    JavaBean转Map工具类
    command line is too long. shorten command line for xxx的解决方法
    Stream流中collect方法
    vue组件传值的方法有哪些
    Collectors.toMap 使用技巧 (List 转 Map超方便)
    Vue formcreate的基本使用
    报错:Unable to load authentication plugin ‘caching_sha2_password‘.
    ElementUi中eltable分页效果,前端控制分页
  • 原文地址:https://www.cnblogs.com/mitsui/p/7202332.html
Copyright © 2020-2023  润新知