[聚合文章] 开发一个博客园系统

Ajax 2017-12-23 17 阅读
开发一个博客园系统

  最近在学django框架,准备用django写一个博客园的系统,并且在写的过程中也遇到一些问题,实践出真知,对django开发web应用方面也有了进一步的了解。很多操作实现都是以我所认知的技术完成的,可能存在不合理的地方(毕竟实现的方法多种多样),基本完成后会将源码上传到git,也欢迎各位大神指正。

  首先,要写未登录主站(index)。这里需要注意文章的分类:

  文章的分类切换,网站本身有定义的文章类型:

   type_choices = [        (1, "Python"),        (2, "Linux"),        (3, "OpenStack"),        (4, "GoLang"),    ]

  要实现主页的分类(分类标签样式要突出)需要使用一个前端与后端都有的id来显示分类。

    if request.method=='GET':        type_id = int(kwargs.get('type_id')) if kwargs.get('type_id') else None        #后台都是get传参        if type_id:            article_list = models.Article.objects.filter(article_type_id=type_id).extra(select={'c': "strftime('%%Y-%%m',create_time)"})        else:            article_list = models.Article.objects.all().extra(select={'c': "strftime('%%Y-%%m',create_time)"})        type_choice_list = models.Article.type_choices#分类的        # print(type_choice_list)#[(1, 'Python'), (2, 'Linux'), (3, 'OpenStack'), (4, 'GoLang')]
后台代码
{% if type_id %}                        <li><a href="/">全部</a></li>                    {% else %}                        <li class="active"><a href="/">全部</a></li>                    {% endif %}                    {% for item in type_choice_list %}                        {% if item.0 == type_id %}                            <li class="active"><a href="/all/{{ item.0 }}/">{{ item.1 }}</a></li>                        {% else %}                            <li><a href="/all/{{ item.0 }}/">{{ item.1 }}</a></li>                        {% endif %}                    {% endfor %}
前端代码

  登陆与注册页面

  登陆与注册的验证使用form表单功能完成,除此之外我们还需要有一个图片验证码用于认证。

   在前端设置一个图片,图片src属性指向后端(获取图片时向后端发生get请求方式,后端返回的),验证码图片由后端生成图片在上面显示,点击更换我们使用每次点击在src属性后面加一个?,这样url改变了前端向后台发送一个get请求,那么就会获得一个新的验证码图片了。

 <img style="width: 120px;height: 30px;" src="/check_code/" title="点击更换" id="change_img">        $(function(){            change_img();        });        function change_img() {//get方式在url上加?刷新图片            $('#change_img').click(function () {                $(this)[0].src=$(this)[0].src+'?';            })        }
前端代码
from PIL import Image,ImageDraw,ImageFont,ImageFilterimport randomdef rd_check_code(width=120, height=30, char_length=4, 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(40):        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())     # 写干扰圆圈    for i in range(40):        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(5):        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)
PIL生成随机码模块
def check_code(request):    from io import BytesIO    from utils.random_check_code import rd_check_code    img,code = rd_check_code()    stream = BytesIO()#开辟一个内存空间,类似于文件句柄    print(stream)#io空间,<_io.BytesIO object at 0x06D6EAE0>    print(img)#pillow生成的图片对象    img.save(stream,'png')    print(stream)    print(stream.getvalue())#bytes类型的图片信息,返回前端生成图片    print(img)    request.session['code'] = code#将生成的随机字符串存到session用于验证    return HttpResponse(stream.getvalue())
后端返回随机码

  登录后将session信息写入浏览器cookie,可以完成两周免登陆效果。注销我使用的时Ajax,后台需要清理session。这个过程中要注意,Ajax需要向后台发送自己的csrf码,否则后端默认是伪造的跨站请求,不给予服务。

 $(function () {            $(".take_off").click(function () {            {#                        $(".take_off").click(function () {#}            {#            $.ajaxSetup({#}            {#                data:{csrfmiddlewaretoken:'{{ csrf_token }}'}#}            {#            });#}                $.ajax({                url:'/',                type:'POST',                {#data:{ 'csrftoken':{{ csrf_token}} },#}                data:{csrfmiddlewaretoken:'{{ csrf_token }}'},                dataType:"JSON",                success:function(arg){                    console.log(arg);                    if(arg.status){                        location.href='/'                    }else{
                

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。