基于Django開(kāi)發(fā)的SkyNet博客四——編輯界面

基于Django開(kāi)發(fā)的SkyNet博客一——?jiǎng)?chuàng)建模型
基于Django開(kāi)發(fā)的SkyNet博客二——base Template
基于Django開(kāi)發(fā)的SkyNet博客三——登錄注冊(cè)界面
代碼傳送門(mén) 這是我這個(gè)項(xiàng)目的github代碼庫(kù),目前項(xiàng)目正在更新隔显,所以代碼不是很全掘而。
上一篇博客主要講了博客的登錄注冊(cè)界面色乾,這一節(jié)想先修改一下上一節(jié)的登錄修改該界面廊营,先來(lái)個(gè)圖吧:

登錄注冊(cè)界面.png

這樣修改主要是因?yàn)榭吹胶芏嗑W(wǎng)站的登錄注冊(cè)都在一個(gè)html上僵控,那么我也就改了一下霜运。改動(dòng)也不多勾邦,主要是html和views.py中修改了一丟丟

{% extends 'blog/base.html' %}
{% block title %}
    SkyNet登錄
{% endblock %}
{% block content %}
    {% load static %}
    <link rel="stylesheet" href="{% static 'blog/css/form.css' %}" type="text/css">
    <script type="text/javascript" src="{% static 'blog/js/login.js' %}"></script>
    <div class="ui middle aligned center aligned grid">
        <div class="column">
            <div class="ui stacked segment">
                <div class="ui two item menu">
                    <a class="item {% if islogin %} active {% endif %}" href="{% url 'blog:login' %}">登錄</a>
                    <a class="item {% if not islogin %} active {% endif %}" href="{% url 'blog:register' %}">注冊(cè)</a>
                </div>
                {% if islogin %}
                    <div id="login-div">
                        <form class="ui login form segment" method="post">

                            <div class="field">
                                <div class="ui input">
                                    <input type="text" placeholder="郵箱或昵稱" name="name">
                                </div>
                            </div>
                            <div class="field">
                                <div class="ui input">
                                    <input type="password" placeholder="密碼" name="pwd">
                                </div>
                            </div>
                            <div class="ui fluid large teal submit button">登錄</div>
                        </form>
                        </div>
                    {% else %}
                        <div id="register-div">
                            <form class="ui register form segment" method="post">
                                <div class="field">
                                    <div class="ui input">
                                        <input type="text" placeholder="昵稱" name="name">
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui input">
                                        <input type="text" placeholder="郵箱" name="email">
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui input">
                                        <input type="password" placeholder="密碼" name="pwd">
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui input">
                                        <input type="password" placeholder="再次輸入密碼" name="pwd2">
                                    </div>
                                </div>

                                <div class="ui fluid large teal submit button">提交</div>
                            </form>
                        </div>
                    {% endif %}
            </div>
        </div>
    </div>
{% endblock %}

其實(shí)改動(dòng)的并不多道川,在上一篇的基礎(chǔ)上合并了兩個(gè)html午衰,添加了一個(gè)menu

<div class="ui two item menu">
    <a class="item {% if islogin %} active {% endif %}" href="{% url 'blog:login' %}">登錄</a>
    <a class="item {% if not islogin %} active {% endif %}" href="{% url 'blog:register' %}">注冊(cè)</a>
</div>

two item menu會(huì)將menu分為平分為兩個(gè)部分立宜,然后通過(guò)views.py傳過(guò)來(lái)的islogin,來(lái)判斷是否該item是否是active臊岸,同樣也可控制顯示登錄窗口還是注冊(cè)窗口橙数。


其他的地方改動(dòng)都很小,主要是views.py中l(wèi)ogin和register最后返回的時(shí)候返回一個(gè)islogin參數(shù)即可

@csrf_exempt
def login(request):
    if request.method == 'POST':
       //和上一篇博客中代碼一致
       ......
    return render(request, 'blog/login.html',{"islogin":True})

登錄注冊(cè)界面就到這里了帅戒。


下面就開(kāi)始來(lái)創(chuàng)建博客編輯界面了灯帮。
同樣的先上個(gè)圖

文章編輯.png

在博客二中的banner上有個(gè)寫(xiě)文章的按鈕


banner-edit.png
//base.html
<div class="item">
    <button id="create_blog" class="ui primary button">寫(xiě)文章</button>
</div>

在js中對(duì)該button的click時(shí)間進(jìn)行了監(jiān)聽(tīng)

//base.js
$("#create_blog").on("click", function () {
    $.ajax({
        type: "get",
        url: "/blog/create_blog/",
        success: function (data) {
            jsonobj = JSON.parse(data);
            if(jsonobj.error == 1) {
                window.location.href = '/blog/login';
            }else {
                window.location.href = '/blog/edit/' + jsonobj.id;
            }
        }
    });
});

這段代碼的主要意圖是點(diǎn)擊寫(xiě)文章按鈕后,通過(guò)后臺(tái)傳遞的error值來(lái)判斷用戶是否登錄逻住,重定向到登錄界面钟哥,若已登錄則重定向到編輯界面。
首先來(lái)看一下create_blog方法

//blog/urls.py
url(r'^create_blog', create_blog, name='create'),
def create_blog(request):
    if request.user.is_authenticated:
        blog = Blog.objects.create(user=request.user)
        return HttpResponse(simplejson.dumps({'error': 0, 'id': blog.pk}, ensure_ascii=False))
    else:
        return HttpResponse(simplejson.dumps({'error': 1}, ensure_ascii=False))

在這里我將models.py中的blog模型改動(dòng)了一下鄙信,所有的值都有默認(rèn)值瞪醋,在創(chuàng)建的時(shí)候只需要傳遞user即可。下面看一下blog models

class Blog(models.Model):
    POST_STATUS = (
        ('P', '已發(fā)布'),
        ('D', '已刪除'),
        ('E', '正在編輯'),
    )

    title = models.CharField('標(biāo)題',max_length=150,default="無(wú)標(biāo)題文章")
    body = models.TextField('正文',blank=True,default="")
    create_time = models.DateTimeField('創(chuàng)建時(shí)間',auto_now_add=True)
    modify_time = models.DateTimeField('最后一次修改',auto_now=True)
    status = models.CharField('文章?tīng)顟B(tài)',max_length=1, choices=POST_STATUS,default='E')
    views = models.PositiveIntegerField('瀏覽量', default=0)
    likes = models.PositiveIntegerField('喜歡', default=0)
    praises = models.PositiveIntegerField('點(diǎn)贊', default=0)
    category = models.ManyToManyField('Category',symmetrical=False,blank=True)
    user = models.ForeignKey('User',verbose_name='作者')

當(dāng)頁(yè)面重定向到編輯界面后装诡,也就是上面第一章圖的效果银受。

//urls.py
url(r'^edit/(?P<blog_id>\d+)', EditBlogView.as_view(), name='edit'),

這里url的定義使用到了TemplateView,也就是封裝好的view請(qǐng)求鸦采,只是開(kāi)放一些接口宾巍,參數(shù)而已。先看一下吧渔伯。

class EditBlogView(DetailView):
    model = Blog
    template_name = 'blog/user/edit.html'
    pk_url_kwarg = 'blog_id'
    context_object_name = 'blog'

    def get_context_data(self, **kwargs):
        context = super(EditBlogView, self).get_context_data(**kwargs)
        blogs = self.request.user.blog_set.all()
        context['blogs'] = blogs
        return context

  1. 繼承DetailView顶霞,展示文章詳情,一般用來(lái)查詢單個(gè)數(shù)據(jù)锣吼。
  2. model即指定的model选浑,將在該model中進(jìn)行數(shù)據(jù)查詢,template_name即指定查詢結(jié)束將數(shù)據(jù)展示的模板中玄叠,pk_url_kwarg指查詢的條件古徒,context_object_name指定查詢返回的結(jié)果。
  3. get_context_data一般用來(lái)傳遞額外的數(shù)據(jù)读恃,這里我將該用戶的所有文章傳遞給了EditBlogView隧膘,用來(lái)制作文章列表顯示。

來(lái)看一下界面結(jié)構(gòu)

{% extends 'blog/base.html' %}
{% block title %}
    文章編輯
{% endblock %}
{% block header %}
{% endblock %}
{% block content %}
    {% load static %}
    <link rel="stylesheet" href="{% static 'blog/css/edit.css' %}" type="text/css">
    <script type="text/javascript" src="{% static 'blog/js/edit.js' %}"></script>
    <i id="blog-id" data-index="{{ blog.pk }}" hidden></i>
    <div id="back-index">
        <a href="{% url 'blog:uindex' request.user.pk %} " class="ui primary button">返回主頁(yè)</a>
    </div>

    {% include 'blog/util/bloglist.html' %}
    <div class="ui center aligned grid">
        <div class="column">
            <div class="ui menu">
                <a id="blog_list" class="item">文章列表</a>
                <div class="right menu">
                    <a id="save_blog" class="ui item">保存</a>
                    <a class="ui item">發(fā)布</a>
                </div>
            </div>
            <form class="ui large form">
                <div class="ui stacked segment">

                    <div class="field">
                        <div class="ui input">
                            <input id="title" type="text" placeholder="標(biāo)題" name="title" value="{{ blog.title }}">
                        </div>
                    </div>
                    <div class="field">

                    </div>
                    <div class="field">
                        <div class="ui input">
                            <textarea id="body" name="body" rows="15">{{ blog.body }}</textarea>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
{% endblock %}

在這里我將主界面分為兩欄寺惫,一個(gè)是菜單欄疹吃,剩下的是標(biāo)題和內(nèi)容欄,其中內(nèi)容列表使用的是{% include %}方式引入一個(gè)html西雀。include和extends用法相同萨驶,include引入的話,可以將頁(yè)面中的功能獨(dú)立出去艇肴,這樣能夠保證頁(yè)面的整體結(jié)構(gòu)篡撵。

先來(lái)看一下保存按鈕功能

$("#save_blog").on("click",function () {
    var $save_msg = $("<a class='ui item'>正在保存</a>");
    $(".right.menu").prepend($save_msg)
    var id = $("#blog-id").attr("data-index");
    var title = $("#title").val();
    var body = $("#body").val();
    $.ajax({
        type:"get",
        url:'../save_blog/'+id,
        data:{
            'title':title,
            'body':body
        },
        success:function (data) {
            $save_msg.text("已保存");
            $save_msg.animate({
                opacity:0,
            },2000,function () {
                $(".right.menu").remove($save_msg);
            });
        }
    })
});

在這里我添加了一個(gè)正在保存的item判莉,然后想后臺(tái)請(qǐng)求保存數(shù)據(jù),最后保存成功則顯示已保存育谬,然后慢慢消失券盅,最后刪除item。

def save_blog(request, blog_id):
    blog = Blog.objects.get(pk=blog_id)
    blog.title = request.POST.get('title')
    blog.body = request.POST.get('body')
    print(blog.title,blog.body)
    blog.save()
    return HttpResponse()

由于這里不需要向前臺(tái)傳遞數(shù)據(jù)膛檀,直接返回HttpResponse即可锰镀。


最后再展示一下sidebar的代碼吧

//bloglist.html
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'blog/css/util/bloglist.css' %}">
<div id="left-menu" class="ui sidebar vertical menu">
    <div class="item">
        <a>返回首頁(yè)</a>
    </div>
    {% for blog in blogs %}
        <div id="menu-item" class="item">
            <a data-index="{{ blog.index }}">{{ blog.title }}</a>
            <i class="trash icon"></i>
        </div>
    {% endfor %}
</div>

//edit.js
$("#blog_list").click(function () {
    $(".ui.sidebar")
        .sidebar('setting', 'transition', 'overlay')
        .sidebar('toggle');
});

編輯界面就先寫(xiě)到這里了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咖刃,一起剝皮案震驚了整個(gè)濱河市泳炉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嚎杨,老刑警劉巖花鹅,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異枫浙,居然都是意外死亡刨肃,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)箩帚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)真友,“玉大人,你說(shuō)我怎么就攤上這事紧帕】唬” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵是嗜,是天一觀的道長(zhǎng)愈案。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鹅搪,這世上最難降的妖魔是什么站绪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮涩嚣,結(jié)果婚禮上崇众,老公的妹妹穿的比我還像新娘掂僵。我一直安慰自己航厚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布锰蓬。 她就那樣靜靜地躺著幔睬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芹扭。 梳的紋絲不亂的頭發(fā)上麻顶,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天赦抖,我揣著相機(jī)與錄音,去河邊找鬼辅肾。 笑死队萤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的矫钓。 我是一名探鬼主播要尔,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼新娜!你這毒婦竟也來(lái)了赵辕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤概龄,失蹤者是張志新(化名)和其女友劉穎还惠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體私杜,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚕键,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歪今。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嚎幸。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寄猩,靈堂內(nèi)的尸體忽然破棺而出嫉晶,到底是詐尸還是另有隱情,我是刑警寧澤田篇,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布替废,位于F島的核電站,受9級(jí)特大地震影響泊柬,放射性物質(zhì)發(fā)生泄漏椎镣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一兽赁、第九天 我趴在偏房一處隱蔽的房頂上張望状答。 院中可真熱鬧,春花似錦刀崖、人聲如沸惊科。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)馆截。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜡娶,已是汗流浹背混卵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窖张,地道東北人幕随。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宿接,于是被迫代替她去往敵國(guó)和親合陵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容