ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bbs技术总结

2020-06-12 21:02:09  阅读:231  来源: 互联网

标签:总结 文件 register obj img admin random 技术 bbs


bbs技术点总结

js只要用到内置对象,直接用new生成就可以了

用户注册上传头像

<div class="form-group">
                <label for="myfile">头像
                    {% load static %}
                    <img id="myimg" src="{% static 'img/default.png' %}" alt="" width="80" style="margin-left: 20px"></label>
                <input type="file" id="myfile" name="avater" style="display: none">
</div>


<script>
    //文本域变化事件
    $('#myfile').change(function () {
        //文件阅读器对象
        //1.先生成一个文件阅读器对象
        let myFileReadObj = new FileReader(); // 文件阅读器
        //2. 获取用户上传的头像文件
        let fileObj = $(this)[0].files[0]; //获取文件
        // 3.将文件对象交给文件阅读器读取
        myFileReadObj.readAsDataURL(fileObj) //异步操作,io操作,这行代码文件还没有读完,就已经开始执行下一句代码,在前端不显示
        //4.利用文件阅读器将文件展示到页面去 修改src属性
        //等待文件阅读器加载完之后,在执行
        myFileReadObj.onload = function(){  $('#myimg').attr('src',myFileReadObj.result)}


    })

  • 这里我们要用到文本与变化事件,利用文件阅读器对象,我们要先生成一个文件阅读器对象,
  • 获取用户上传的头像文件读取出来
  • 将文件对象交给文件阅读器读取出来文件
  • 利用文件阅读器将文件展示到页面上去,就要修改src属性,myFileReadObj.readAsDataURL(fileObj) $('#myimg').attr('src',myFileReadObj.result)这两部是一个异步操作,如果你在执上一代码的同时文件还没有读取出来,同时他还在执行下一句代码,这样会造成你上传之后在前端是不显示你上传的头像,空白区,我们要等文件加载完毕在执行下一局, myFileReadObj.onload
 $('#id_commit').click(function () {
        // 发送ajax请求     我们发送的数据中即包含普通的键值也包含文件
        let formDataObj = new FormData();
        // 1.添加普通的键值对
        {#console.log($('#myform').serializeArray())  // [{},{},{},{},{}]  只包含普通键值对#}
        $.each($('#myform').serializeArray(),function (index,obj) {
            {#console.log(index,obj)#}  // obj = {}
            formDataObj.append(obj.name,obj.value)
        });
        // 2.添加文件数据
        formDataObj.append('avatar',$('#myfile')[0].files[0]);

        // 3.发送ajax请求
        $.ajax({
            url:"",
            type:'post',
            data:formDataObj,

            // 需要指定两个关键性的参数
            contentType:false,
            processData:false,

            success:function (args) {
                if (args.code==1000){
                    // 跳转到登陆页面
                    window.location.href = args.url
                }els
                    // 如何将对应的错误提示展示到对应的input框下面
                    // forms组件渲染的标签的id值都是 id_字段名
                    $.each(args.msg,function (index,obj) {
                        {#console.log(index,obj)  //  username        ["用户名不能为空"]#}
                        let targetId = '#id_' + index;
                        $(targetId).next().text(obj[0]).parent().addClass('has-error')
                    })
                }
            }
        })
    })


def register(request):
    # 产生一个空对象
    register_form = myforms.MyRegForm()
    if request.method == 'POST':
        back_dic = {'code':'', 'msg': ''}
        # 校验数据是否合法
        register_form = myforms.MyRegForm(request.POST)
        # 判断数据是否合法
        if register_form.is_valid():
            clean_data = register_form.cleaned_data # 将校验通过的数据字典赋值给一个变量
            # 将字典里面吗的confirm_password键值对删除
            clean_data.pop('confirm_password')
            # 用户头像
            file_obj = request.FILES.get('avatar')
            """
            针对用户头像一定要判断是否传之,不能直接添加到字典里面去
            """
            if file_obj:
                clean_data['avatar'] = file_obj
            # 直接操作数据库保存到字典里面
            models.UserInfo.objects.create_user(**clean_data) # 将键值对**打散传到数据库
            # 判断正确跳转到登录页面
            back_dic['url'] = '/login/'
        else:
            back_dic['code'] = 2000
            back_dic['msg'] = register_form.errors
            return JsonResponse(back_dic)

    return render(request, 'register.html', locals())

前端:

  • 头像的功能完成之后,剩下的就是将利用ajax将文件发送到后端,前端要先利用内置对象获取数据,添加不同键值对,我们可以利用serializeArray()拿到他所有的键值对,利用each循环拿到每一个对象的键值对

  • 利用append添加文件数据,发送ajax请求,这里面我们要指定两个关键参数contentType: false,processData: false,

  • 如果后端保存数据成功,就跳转到后端写好传过来的指定页面,如果校验数据失败就在input框下面展现出对应的错误

  • 当我们看见错误的信息之后,如果把鼠标放上去,指定的错误就会消失,给所有的input框绑定获取焦点事件,将input下面的span标签和input外面的div标签修改内容和属性

后端

  • 校验数据输入的是否合法,将合法的数据赋值给一个变量,赋值给一个变量方便我们删除确认密码的键值对,因为我们在写models的时候没有这个字段,针对用户头像一定要判断是否传之,不能直接添加到字典里面去,在models里面我们给他默认了一个头像
  • 操作数据库保存数据,定义字典将信息返回给ajax,ajax都到在页面展示对应的页面信息

生成登录验证码

如何生成一个验证码,然后点击它就可以刷新呢。

利用pip3 install pillow ,这个是图片相关的模块。

导入模块:from PIL import Image, ImageDraw, ImageFont

  • Image 生成图片
  • ImageDraw 能够在图片上添加东西
  • ImageFont 控制字体的样式

推导1

直接获取后端生成的图片二进制数据发送给前端

with open(r'static/img/111.jpg','rb') as f:
      data = f.read()
return HttpResponse(data)

推导2

利用pillow模块动态产生图片

img_obj = Image.new('RGB',(430,35),'green')
img_obj = Image.new('RGB',(430,35),get_random())

# 将图片对象 保存起来
with open('xxx.png','wb') as f:
    img_obj.save(f,'png')
# 再将文件对象读取出来
with open('xxx.png','rb') as f:
    data = f.read()
return HttpResponse(data)

推导3
我们可以看到利用文件存储繁琐而且IO操作效率低,我们可以借助内存管理模块

from io import BytesIO,StringIO
img_obj = Image.new('RGB', (430, 35), get_random())
io_obj = BytesIO()
img_obj.save(io_obj,'png') # 生成一个内存管理器对象
return HttpResponse(io_obj.getvalue()) # 从内存管理器中读取二进制的图片数据返回给前端

推导4

写成图片验证码

img_obj = Image.new('RGB', (430, 35), get_random())
img_draw = ImageDraw.Draw(img_obj)  # 产生一个画笔对象
img_font = ImageFont.truetype('static/font/222.ttf',30)  # 字体样式 大小

最终成型

import random
def get_random():
    return random.randint(0,255),random.randint(0,255),random.randint(0,255)
def get_code(request):
    img_obj = Image.new('RGB', (430, 35), get_random()) # 注意:这里的430,35要和前端的一致
    img_draw = ImageDraw.Draw(img_obj)
    img_font = ImageFont.truetype('static/font/222.ttf',30)
    code = ''
    for i in range(5):
        random_upper = chr(random.randint(65,90))
        random_lower = chr(random.randint(97,122))
        random_int = str(random.randint(0,9))
        tmp = random.choice([random_lower,random_upper,random_int])
        img_draw.text((i*60+60,-2),tmp,get_random(),img_font)
        code += tmp
    print(code)
    request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj,'png')
    return HttpResponse(io_obj.getvalue())

  • 实现低级验证码图片刷新验证码,这样设置后每次点击图片相当于超后端发送一次get请求获取一个新的验证码图片
{# 点击验证码图片刷新验证码   #}
$('#code_img').click(function () {
    $(this).attr('src', '{% url "get_code" %}?')	// src='/get_code/?'url后面加?的操作
});

admin的使用

以前写图书的展示列表,我们给它添加增删改查的功能,特别的麻烦,现在有很多张表的展示,我们不可能慢慢的写这些功能,django给我们提供了admin后台管理,我们可以利用admin实现增删改查,添加数据。

首先要创建超级用户,只有超级用户才能够操作admin的这些功能。

刚开始登录进去的时候只用一张用户表,我们想要添加其他的表,必须添加注册

from django.contrib import admin
from app01 import models
# Register your models here.admin
admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Article)
admin.site.register(models.Atricle2Tag)
admin.site.register(models.UpAndDown)
admin.site.register(models.Category)
admin.site.register(models.Tag)
admin.site.register(models.Comment)

这样我们就可以使用这些表,但是他们是英文的,我们可以在model.py里面改变他们的名字

class Meta:
     verbose_name_plural='用户表'

我们进去操作添加添加一条数据显示的是对象,

class UserInfo(AbstractUser):
    ...
def __str__(self):
        return self.username	

避免造成不便语义不明,打印出来

在model里面的字段添加verbose_name='创建时间'会在admin后天帮助我们把字段的名称改成中文

制作站点

打开博客园,在博客园的url后面输入别人的站点名称就可以进到他们的站点,如https://home.cnblogs.com/the3times在后面输入the3times就会进到这个人的博客园的主页,这个是url来配置的,利用urlre匹配规则就可以实现

url(r'^(?P<username>\w+)/$',views.site,name='site'),

media的配置

网站用户使用的静态文件默认放在static里面,用户上传的静态文件应该单独放在一个文件夹下,可以使用media配置,该配置可以让用户上传的所有的文件 固定存放在指定的文件夹下

settings.py

# 配置用户上传的文件
MEDIA_ROOT = os.path.jion(BASE_DIR,'media')

我们配置后,我们上传文件会自动生成media文件,比如我们注册上传的头像会到这个地方,你存的路径在数据库中也不会改变,

假如你在model.py里面存的路径是avatar/111.pngmedia里面就会多出一个存放头像的avatar/111.png这个就是你存放的头像路径。

class UserInfo(AbstractUser):
    avatar = models.FileField(upload_to='avatar/', default='avatar/default.png', verbose_name='用户头像')

在前端点击这个头像能够查看到这个头像,需要我们在后端开设一个指定的文件夹资源

在url.py配置参数

from django.views.static import serve
from bbs import settings

url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT}),

如果你还想暴漏更多资源,在settings修改文件夹名,想暴露源码也可以,问题就大了

最后在html配置,渲染后的路径/media/avatar/default.png/

<img class="media-object" src="/media/{{ article_obj.blog.userinfo.avatar }}" alt="..." width="40">

这样就可以看到别人的头像

标签:总结,文件,register,obj,img,admin,random,技术,bbs
来源: https://www.cnblogs.com/zc110/p/13110307.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有