zoukankan      html  css  js  c++  java
  • Django+Nginx+uwsgi搭建自己的博客(七)

    上一篇博客中介绍了Blogs App的部分后端功能的实现,在这篇博客中,将继续为大家介绍Blogs App中前端功能的实现。

    首先来看发布博客功能的前端页面。在blogs/templates/blogs目录下建立名为addBlog.html的文件,作为我们的发布博客页面。addBlog.html内容如下:

    1. <!-- addBlog.html -->  
    2. {% extends "blogTemplate.html" %}  
    3. {% block content %}  
    4. <div class="content">  
    5. <form action="{% url 'blogs:addblog' %}" method="post">  
    6. {% csrf_token %}  
    7. {{ form.as_p }}  
    8. <input type="submit" value="保存并提交">  
    9. <input type="button" id="saveDraft" value="保存到草稿">  
    10. <div id="tip" >  
    11. </div>  
    12. </form>  
    13. </div>  
    14. <script>  
    15.     CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});  
    16. </script>  
    17. <script>  
    18. $("#saveDraft").click(function(){  
    19.     var blogContent = "";  
    20.     try  
    21.     {  
    22.         blogContent = CKEDITOR.instances.id_content.getData();  
    23.     }  
    24.     catch(ex){}  
    25.     $.post("{% url 'blogs:saveDraft' %}",  
    26.     {  
    27.         title:$("#id_title").val(),  
    28.         category:$("#id_category").val(),  
    29.         content:blogContent,  
    30.         csrfmiddlewaretoken:'{{ csrf_token }}'  
    31.     },  
    32.     function(data,status)  
    33.     {  
    34.         var mydate = new Date();  
    35.           
    36.         $("#tip").html("<p>文章已存为草稿于"+mydate.toLocaleString()+"</p>");  
    37.         $("#tip").show();  
    38.         $("#tip").delay(5000).hide(0);  
    39.     });  
    40. });  
    41. </script>  
    42. <script>  
    43. function saveDraft(){  
    44.     var blogContent = "";  
    45.     try  
    46.     {  
    47.         blogContent = CKEDITOR.instances.id_content.getData();  
    48.     }  
    49.     catch(ex){}  
    50.     $.post("{% url 'blogs:saveDraft' %}",  
    51.     {  
    52.         title:$("#id_title").val(),  
    53.         category:$("#id_category").val(),  
    54.         content:blogContent,  
    55.         csrfmiddlewaretoken:'{{ csrf_token }}'  
    56.     },  
    57.     function(data,status)  
    58.     {  
    59.         var mydate = new Date();  
    60.         $("#tip").html("<p>文章已存为草稿于"+mydate.toLocaleString()+"</p>");  
    61.     });  
    62. }  
    63. setInterval(saveDraft,60000);  
    64. </script>  
    65. </div>  
    66. {% endblock %}  
    <!-- addBlog.html -->
    {% extends "blogTemplate.html" %}
    {% block content %}
    <div class="content">
    <form action="{% url 'blogs:addblog' %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="保存并提交">
    <input type="button" id="saveDraft" value="保存到草稿">
    <div id="tip" >
    </div>
    </form>
    </div>
    <script>
        CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});
    </script>
    <script>
    $("#saveDraft").click(function(){
        var blogContent = "";
        try
        {
            blogContent = CKEDITOR.instances.id_content.getData();
        }
        catch(ex){}
        $.post("{% url 'blogs:saveDraft' %}",
        {
            title:$("#id_title").val(),
            category:$("#id_category").val(),
            content:blogContent,
            csrfmiddlewaretoken:'{{ csrf_token }}'
        },
        function(data,status)
        {
            var mydate = new Date();
            
            $("#tip").html("<p>文章已存为草稿于"+mydate.toLocaleString()+"</p>");
            $("#tip").show();
            $("#tip").delay(5000).hide(0);
        });
    });
    </script>
    <script>
    function saveDraft(){
        var blogContent = "";
        try
        {
            blogContent = CKEDITOR.instances.id_content.getData();
        }
        catch(ex){}
        $.post("{% url 'blogs:saveDraft' %}",
        {
            title:$("#id_title").val(),
            category:$("#id_category").val(),
            content:blogContent,
            csrfmiddlewaretoken:'{{ csrf_token }}'
        },
        function(data,status)
        {
            var mydate = new Date();
            $("#tip").html("<p>文章已存为草稿于"+mydate.toLocaleString()+"</p>");
        });
    }
    setInterval(saveDraft,60000);
    </script>
    </div>
    {% endblock %}
    这个页面在显示的方面比较简单,就是将我们在上一篇博客中建立好的BlogForm表单显示在页面上。注意,为了使用CKeditor,我们需要使用以下的javascript语句对我们的文本域进行替换:
    [javascript] view plain copy
    print?
    1. <script>  
    2.     CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});  
    3. </script>  
    <script>
        CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});
    </script>
    其中,blogcontent是我们文本域的id,而uiColor意味着我们可以为这个文本框指定颜色。

    在该页面中,另外一个功能是将正在编辑的文章存储为草稿。由于保存草稿的操作不允许提交表单后跳转页面,因此我们需要使用jquery ajax的方式提交表单。在这里,我们提供了两种方式将文章保存草稿:1、通过用户手动点击保存按钮来存为草稿;2、每隔1分钟自动保存草稿。首先来看通过按钮来保存的javascript代码:

    [javascript] view plain copy
    print?
    1. <script>  
    2. $("#saveDraft").click(function(){  
    3.     var blogContent = "";  
    4.     try  
    5.     {  
    6.         blogContent = CKEDITOR.instances.id_content.getData();  
    7.     }  
    8.     catch(ex){}  
    9.     $.post("{% url 'blogs:saveDraft' %}",  
    10.     {  
    11.         title:$("#id_title").val(),  
    12.         category:$("#id_category").val(),  
    13.         content:blogContent,  
    14.         csrfmiddlewaretoken:'{{ csrf_token }}'  
    15.     },  
    16.     function(data,status)  
    17.     {  
    18.         var mydate = new Date();  
    19.           
    20.         $("#tip").html("<p>文章已存为草稿于"+mydate.toLocaleString()+"</p>");  
    21.         $("#tip").show();  
    22.         $("#tip").delay(5000).hide(0);  
    23.     });  
    24. });  
    25. </script>  
    <script>
    $("#saveDraft").click(function(){
        var blogContent = "";
        try
        {
            blogContent = CKEDITOR.instances.id_content.getData();
        }
        catch(ex){}
        $.post("{% url 'blogs:saveDraft' %}",
        {
            title:$("#id_title").val(),
            category:$("#id_category").val(),
            content:blogContent,
            csrfmiddlewaretoken:'{{ csrf_token }}'
        },
        function(data,status)
        {
            var mydate = new Date();
            
            $("#tip").html("<p>文章已存为草稿于"+mydate.toLocaleString()+"</p>");
            $("#tip").show();
            $("#tip").delay(5000).hide(0);
        });
    });
    </script>

    这段代码的主体可以抽象成如下形式:

    [javascript] view plain copy
    print?
    1. <script>  
    2. $("#saveDraft").click(function(){});  
    3. </script>  
    <script>
    $("#saveDraft").click(function(){});
    </script>
    在上面的表单中,可以看到我们创建了一个id为saveDraft的按钮,因此这里可以通过$("#saveDraft")来访问此按钮,并且指定当单击该按钮时执行这个匿名function。

    在这个匿名function中,我们可以通过blogContent = CKEDITOR.instances.id_content.getData();来取得当前CKeditor编辑器中的内容,并通过POST的方式将表单内容发送给服务器。在这里,我们使用jquery ajax的$.post方法来提交表单。该方法包括三个参数:url,data和callback函数。url即为表单要提交到的地址,这里我们依然可以使用Django提供的{% url %}标记作为url;而data是我们要提交的数据。与一般的提交表单相比,这里的数据需要以json的格式发送给服务器;而callback是回调函数,即当表单内容被发送给服务器后要执行的程序,这里我们会显示存为草稿的时间,并且显示5秒后消失。

    定时存储为草稿的功能与这段代码基本完全一样,只是把这个匿名函数加了个saveDraft的名称,然后加上了setInterval(saveDraft,60000);这句,以便每隔60s便调用一次此函数,将文章存为草稿,如下所示:

    在成功发布博客后,页面会跳转到addblogResult.html页面中,该页面比较简单,代码如下所示:

    1. {% extends "blogTemplate.html" %}  
    2. {% block content %}  
    3. <div class="content">  
    4. {{ info }}  
    5. </div>  
    6. <p><a href="{% url 'index' %}">返回首页</a></p>  
    7. {% endblock %}  
    {% extends "blogTemplate.html" %}
    {% block content %}
    <div class="content">
    {{ info }}
    </div>
    <p><a href="{% url 'index' %}">返回首页</a></p>
    {% endblock %}

    现在,我们已经可以发布自己的博客了。下面让我们看看如何发布评论。首先还是先来看后端部分,我们编写了saveComment函数用于发布评论,如下所示:

    1. # blogs/views.py  
    2. # ...  
    3. def saveComment(request):  
    4.     comment_content = request.POST['blogcomment']  
    5.     blog = Blog.objects.get(pk=request.session['currblogId'])  
    6.     result_info = ''  
    7.     try:  
    8.         auther = Users.objects.get(username=request.session['username'])  
    9.     except KeyError:  
    10.         auther = Users.objects.get(username='anony')  
    11.     try:  
    12.         mycomment = Comment.create(blog,comment_content,auther,datetime.datetime.now())  
    13.         blog.commentcount = blog.commentcount + 1  
    14.         blog.save()  
    15.         mycomment.save()  
    16.         result_info = 'Success'  
    17.     except ValidationError as e:  
    18.         result_info = 'Fail'  
    19.     return HttpResponseRedirect(reverse('blogs:content',kwargs={'blogId':request.session['currblogId']}))  
    20. # ...  
    # blogs/views.py
    # ...
    def saveComment(request):
        comment_content = request.POST['blogcomment']
        blog = Blog.objects.get(pk=request.session['currblogId'])
        result_info = ''
        try:
            auther = Users.objects.get(username=request.session['username'])
        except KeyError:
            auther = Users.objects.get(username='anony')
        try:
            mycomment = Comment.create(blog,comment_content,auther,datetime.datetime.now())
            blog.commentcount = blog.commentcount + 1
            blog.save()
            mycomment.save()
            result_info = 'Success'
        except ValidationError as e:
            result_info = 'Fail'
        return HttpResponseRedirect(reverse('blogs:content',kwargs={'blogId':request.session['currblogId']}))
    # ...

    这段程序和Users App中的登录程序有相似的地方,都是通过request.POST的方式取得表单的数据,然后进行后续操作。与发布博客不同的是,这里使用了Comment Model中建立的create函数来建立新的Comment数据,通过create函数,我们可以更加灵活地决定Model中每个字段的值。还需注意的一点是,在成功发布评论后,我们并没有跳转到一个新的页面,而是仍然跳转到当前浏览的博客的页面,因此我们可以立刻看到我们发布的评论:

    而发布评论的前端部分在上一篇博客中介绍content页面的部分中已经包括了,这里再搬运一下:

    1. <!-- blogs/templates/blogs/content.html -->    
    2. {% extends "blogTemplate.html" %}    
    3. {% block content %}    
    4. <div class="content">    
    5. <h2>{{ blog_title }}</h2>    
    6. {{ content|safe }}    
    7. </div>    
    8. <p><a href="{% url 'index' %}">返回首页</a></p>    
    9. {% endblock %}    
    10. {% block comment %}    
    11. {% if comment_list %}    
    12.         
    13.     {% for comment in comment_list %}    
    14.         <ul class="comment">    
    15.         <li>    
    16.         {% if comment.auther.username == "anony" %}    
    17.         <h4>匿名用户    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>    
    18.         {% else %}    
    19.                 <img src="{{ comment.auther.logoimage.url }}" width="64" height="64" />    
    20.         <h4>{{ comment.auther }}    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>    
    21.         {% endif %}    
    22.         </li>    
    23.         <li>{{ comment.content|safe }}</li>    
    24.         </ul>    
    25.         <hr/>    
    26.     {% endfor %}    
    27. {% else %}    
    28.     <ul class="comment">    
    29.     <p>还没有人发表评论</p>    
    30.     </ul>    
    31. {% endif %}    
    32. <span>评论 </span>    
    33. <form action="{% url 'blogs:saveComment' %}" method="post">    
    34. {% csrf_token %}    
    35. <ul class="comment">    
    36. <li><textarea name="blogcomment"></textarea></li>    
    37. <li><input type="submit" value="提交"></li>    
    38. </ul>    
    39. </form>    
    40. {% endblock %}   
    <!-- blogs/templates/blogs/content.html -->  
    {% extends "blogTemplate.html" %}  
    {% block content %}  
    <div class="content">  
    <h2>{{ blog_title }}</h2>  
    {{ content|safe }}  
    </div>  
    <p><a href="{% url 'index' %}">返回首页</a></p>  
    {% endblock %}  
    {% block comment %}  
    {% if comment_list %}  
          
        {% for comment in comment_list %}  
            <ul class="comment">  
            <li>  
            {% if comment.auther.username == "anony" %}  
            <h4>匿名用户    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>  
            {% else %}  
                    <img src="{{ comment.auther.logoimage.url }}" width="64" height="64" />  
            <h4>{{ comment.auther }}    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>  
            {% endif %}  
            </li>  
            <li>{{ comment.content|safe }}</li>  
            </ul>  
            <hr/>  
        {% endfor %}  
    {% else %}  
        <ul class="comment">  
        <p>还没有人发表评论</p>  
        </ul>  
    {% endif %}  
    <span>评论 </span>  
    <form action="{% url 'blogs:saveComment' %}" method="post">  
    {% csrf_token %}  
    <ul class="comment">  
    <li><textarea name="blogcomment"></textarea></li>  
    <li><input type="submit" value="提交"></li>  
    </ul>  
    </form>  
    {% endblock %} 

    这段代码中最下方的表单就是我们发布评论所用到的。由于Comment Model没有涉及文件的上传操作,因此我们没有采用ModelForm的形式,而是自己在前端组织表单,并将对应的值发送给后端。对于一些不太复杂的Model,采用自己设计的表单可能会更方便。 截止到这篇博客,Users App和Blogs App的核心功能已经完成了,我们现在实现的功能有:用户注册、用户登录、退出登录、查看用户资料、发布博客、将博客存为草稿、发布评论以及浏览博客等。从下篇博客开始,将会继续开发与Users App和Blogs App相关的管理功能,包括编辑博客、删除博客、修改用户信息等功能,希望大家继续关注~
  • 相关阅读:
    newCachedThreadPool无上限线程池使用
    newFixedThreadPool固定线程使用
    java定时器
    http文件上传/下载
    ThreadPoolExecutor线程池
    阻塞队列
    非阻塞队列
    IO文件夹拷贝(文件内含有文件和文件夹)
    MD5加密
    web.xml文件的作用
  • 原文地址:https://www.cnblogs.com/xiaoyaojinzhazhadehangcheng/p/8360480.html
Copyright © 2011-2022 走看看