Django + Django Rest Framwork + Vue 實(shí)現(xiàn) 增刪改查

Django + Django Rest Framwork + Vue 實(shí)現(xiàn) 增刪改查

[TOC]

主要分兩步

  • Django+Rest實(shí)現(xiàn)API
  • Vue 利用API接口實(shí)現(xiàn)增刪改查

目前已經(jīng)完成

Django + Rest Framework 實(shí)現(xiàn)API

省略創(chuàng)建Django項(xiàng)目和導(dǎo)出數(shù)據(jù)等操作

首先安裝djangorestframework振峻,我們使用conda安裝俱济,由于默認(rèn)的conda沒(méi)有這個(gè)庫(kù)挤聘,所以需要運(yùn)行下面命令解決

 conda config --add channels conda-forge
 conda install djangorestframework

安裝成功后士袄,我們?cè)贒jango項(xiàng)目的setting.py中引入

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 引入我們的rest_framwwork
    'rest_framework',
    # 我們自己的應(yīng)用
    'news'
]

先看一下我們的news應(yīng)用,這個(gè)應(yīng)用自己創(chuàng)建进倍,這里不是重點(diǎn)女坑。我們看一下news中的models.py數(shù)據(jù)

class Column(models.Model):
    # 字段信息 
    name = models.CharField('欄目名稱(chēng)', max_length=256)
    # db_index 自增序列
    slug = models.CharField('欄目網(wǎng)址', max_length=256, db_index=True)
    intro = models.TextField('欄目簡(jiǎn)介', default='')

    nav_display = models.BooleanField('導(dǎo)航顯示', default=False)
    home_display = models.BooleanField('首頁(yè)顯示', default=False)
    
    # 下面部分可有可無(wú)肖油,在這里不做重點(diǎn)
    def __str__(self):
        return self.name
    def get_absolute_url(self):
        return reverse('news:column', args=(self.slug,))

    class Meta:
        verbose_name = '欄目'
        verbose_name_plural = '欄目'
        ordering = ['name']

接下來(lái)我們?cè)趎ews目錄下創(chuàng)建一個(gè) serializer.py文件。這個(gè)文件的作用是用來(lái)將我們數(shù)據(jù)庫(kù)內(nèi)容序列化成json格式烦绳。該文件內(nèi)容如下

from rest_framework import serializers
from .models import Column, Article

class ColumnSerializer(serializers.ModelSerializer):    
    class Meta:
        model = Column
        fields = '__all__'

然后我們?cè)?code>views.py中設(shè)置一個(gè)模型集合卿捎,代碼如下

from .models import Column, Article

from rest_framework import viewsets
from .serializer import ColumnSerializer

class ColumnViewSet(viewsets.ModelViewSet):
    queryset = Column.objects.all()
    serializer_class = ColumnSerializer

接下來(lái)我們?nèi)?code>urls.py中映射我們的url和view

先在news中建立一個(gè)urls.py文件,再到根目錄中的urls.py使用下面代碼引入我們的news中的urls

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('news.urls'))
]

再到news中的urls.py中注冊(cè)剛剛的集合径密,代碼如下

from django.urls import path, re_path, include
# 引入rest framework中的routers
from rest_framework import routers
from . import views

app_name = 'news'

# framework中的路由進(jìn)行了封裝
router = routers.DefaultRouter()
router.register(r'column', views.ColumnViewSet)
router.register(r'article', views.ArticleViewSet)

# 前面三個(gè)path可以忽略娇澎,這是我自己之前寫(xiě)的
urlpatterns = [
    path('', views.index, name='index'),
    re_path(r'column/(?P<column_slug>[^/]+)/$', views.column_detail, name='column'),
    re_path(r'article/(?P<pk>\d+)/(?P<article_slug>[^/]+)/$', views.article_detail, name='article'),
    # 主要代碼
    path(r'api/', include(router.urls)),
]

最后在運(yùn)行我們的程序,輸入地址http://127.0.0.1:8000/api/可以看到下面界面即證明成功

3XlWxfVZrBn4aYH

點(diǎn)進(jìn)去可以看到我們的API對(duì)數(shù)據(jù)進(jìn)行對(duì)請(qǐng)求

Vue中實(shí)現(xiàn)增刪改查

Vue的創(chuàng)建以及一些組件的初始化不做介紹

我們創(chuàng)建一個(gè)請(qǐng)求API的測(cè)試組件睹晒,比如我這里叫Rest.vue,然后在路由中引入趟庄。因?yàn)樾枰l(fā)送請(qǐng)求,所以我們使用axios實(shí)現(xiàn)請(qǐng)求伪很,axios自行安裝戚啥。我們?cè)?code>main.js中引入

import axios from 'axios
Vue.prototype.$http = axios

接下來(lái)在Rest.vue編寫(xiě)我們的視圖以及一些相關(guān)方法

<template>
  <div class="box">
    <h1>{{title}}</h1>
    <ul>
      <li
        v-for="(column, index) in columns"
        :key="index"
      >{{index}} - {{column.name}} - {{column.slug}} - <button @click="deleteColumn(column.id)">x</button>
      </li>
    </ul>
    <form action>
      name:
      <input type="text" placeholder="book name" v-model="columnEntity.name" />
      <br />slug:
      <input type="text" placeholder="book author" v-model="columnEntity.slug" />
      <br />intro:
      <input type="text" placeholder="book author" v-model="columnEntity.intro" />
      <br />nav_display:
      <input
        type="checkbox"
        placeholder="book author"
        v-model="columnEntity.nav_display"
      />
      <br />home_display:
      <input
        type="checkbox"
        placeholder="book author"
        v-model="columnEntity.home_display"
      />
      <br />
    </form>
    <button type="submit" @click="submit()">submit</button>
    <button @click="rediect">重定向</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: "測(cè)試API",
      columns: null,
      columnEntity: {
        name: "",
        slug: "",
        intro: "",
        nav_display: false,
        home_display: false
      }
    };
  },
  mounted() {
    this.getData();
  },
  methods: {
    submit() {
      console.log(this.columnEntity);
      this.$http
        .post("http://127.0.0.1:8000/api/column/", {
          name: this.columnEntity.name,
          slug: this.columnEntity.slug,
          intro: this.columnEntity.intro,
          nav_display:
            this.columnEntity.nav_display === null
              ? false
              : this.columnEntity.nav_display,
          home_display:
            this.columnEntity.home_display === null
              ? false
              : this.columnEntity.home_display
        })
        .then(res => {
          console.log(res);
          this.getData();
          // 成功的話,重定向到這個(gè)頁(yè)面
          // this.rediect();
        });
    },
    rediect() {
      // 該方法定向無(wú)法定向到當(dāng)前路由
      // this.$router.push("Rest");
      window.location.reload();
    },
    getData() {
      this.$http.get("http://127.0.0.1:8000/api/column/").then(res => {
        console.log(res);
        this.columns = res.data;
      });
    },
    deleteColumn(id) {
        console.log(`刪除 ->${id}`);
        this.$http.get('http://127.0.0.1:8000/api/column/', {
            id: id
        }).then(res => {
            console.log(res);
            
        })
    }
  }
};
</script>

<style>
</style>

這里存在跨域請(qǐng)求的問(wèn)題锉试,我們解決一下猫十,跨域的話需要在服務(wù)端進(jìn)行解決。所以我們需在Django項(xiàng)目中使用django-cors-headers呆盖。

先進(jìn)行安裝 conda install django-cors-headers

再到settings.py中注冊(cè)我們的應(yīng)用并進(jìn)行如下配置

INSTALLED_APPS = [
    ....,
    # 支持跨域
    'corsheaders'
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # 需注意與其他中間件順序拖云,這里放在最前面即可
    ...
]

# 支持跨域配置開(kāi)始
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True 

最后我們先看一下我們的界面

pSkfhqexbsTFgYI

我們看一下獲取列表的請(qǐng)求是如何發(fā)送的

getData() {
  this.$http.get("http://127.0.0.1:8000/api/column/").then(res => {
    console.log(res);
    this.columns = res.data;
  });
},

然后看一下添加一條數(shù)據(jù)的請(qǐng)求代碼

submit() {
  console.log(this.columnEntity);
  this.$http
    .post("http://127.0.0.1:8000/api/column/", {
      name: this.columnEntity.name,
      slug: this.columnEntity.slug,
      intro: this.columnEntity.intro,
      nav_display:
        this.columnEntity.nav_display === null
          ? false
          : this.columnEntity.nav_display,
      home_display:
        this.columnEntity.home_display === null
          ? false
          : this.columnEntity.home_display
    })
    .then(res => {
      console.log(res);
      // 發(fā)送成功后,重新獲取數(shù)據(jù)应又,更新當(dāng)前頁(yè)面的數(shù)據(jù)列表
      this.getData();
    });
}

接下來(lái)需要處理的

  • 如何根據(jù)條件獲取數(shù)據(jù)
  • 如何刪除數(shù)據(jù)
  • 如何更新數(shù)據(jù)

獲取數(shù)據(jù)的功能實(shí)現(xiàn)

根據(jù)官方文檔可以看到過(guò)濾有三種方式

下面三種方式只是Get宙项,并不能修改

  • 只顯示當(dāng)前用戶(hù)
  • 通過(guò)URL過(guò)濾
  • 通過(guò)參數(shù)過(guò)濾

上面三種方式可以看另一篇文章

我們使用下面這種方式獲取我們的數(shù)據(jù)

http://127.0.0.1:8000/api/column/<id>/

這里的id是你數(shù)據(jù)庫(kù)中那條數(shù)據(jù)的id,這樣就可以獲取到我們想要的單條數(shù)據(jù)了株扛。比如下面

輸入http://127.0.0.1:8000/api/column/16/獲得id為16的數(shù)據(jù),同時(shí)也可以看到這個(gè)API接口有putdelete方法

XxMYzIBNbRy3SVF

確定好如何獲取數(shù)據(jù)的方法后尤筐,我們到Vue中寫(xiě)我們處理的邏輯。代碼如下

getInfo(id) {
  this.$http
    .get(`http://127.0.0.1:8000/api/column/${id}/`, {
      id: id
    })
    .then(res => {
      // 獲取數(shù)據(jù)成功后的操作
      this.columnEntity = res.data
      this.currentId = id
    });
},

刪除接口

根據(jù)上面到API接口洞就,我們可以很容易到寫(xiě)出刪除的方法盆繁。這里直接上代碼吧

deleteColumn(id) {
  this.$http.delete(`http://127.0.0.1:8000/api/column/${id}/`).then(res => {
    console.log(res);
    this.getData();
  });
},

更新接口

更新接口也很簡(jiǎn)單,直接看代碼

updateInfo() {
  console.log("更新信息", this.currentId);
  this.$http
    .put(`http://127.0.0.1:8000/api/column/${this.currentId}/`, {
      name: this.columnEntity.name,
      slug: this.columnEntity.slug,
      intro: this.columnEntity.intro,
      nav_display:
        this.columnEntity.nav_display === null
          ? false
          : this.columnEntity.nav_display,
      home_display:
        this.columnEntity.home_display === null
          ? false
          : this.columnEntity.home_display
    })
    .then(res => {
      console.log(res);
      this.getData();
    });
}

結(jié)果展示

如果所示

9TFEQx3Zy6OaLgA

詳細(xì)代碼請(qǐng)看

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旬蟋,一起剝皮案震驚了整個(gè)濱河市油昂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖冕碟,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稠腊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鸣哀,警方通過(guò)查閱死者的電腦和手機(jī)架忌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)我衬,“玉大人叹放,你說(shuō)我怎么就攤上這事∧痈幔” “怎么了井仰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)破加。 經(jīng)常有香客問(wèn)我俱恶,道長(zhǎng),這世上最難降的妖魔是什么范舀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任合是,我火速辦了婚禮,結(jié)果婚禮上锭环,老公的妹妹穿的比我還像新娘聪全。我一直安慰自己,他們只是感情好辅辩,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布难礼。 她就那樣靜靜地躺著,像睡著了一般玫锋。 火紅的嫁衣襯著肌膚如雪蛾茉。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天撩鹿,我揣著相機(jī)與錄音谦炬,去河邊找鬼。 笑死三痰,一個(gè)胖子當(dāng)著我的面吹牛吧寺,可吹牛的內(nèi)容都是我干的窜管。 我是一名探鬼主播散劫,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼幕帆!你這毒婦竟也來(lái)了获搏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎常熙,沒(méi)想到半個(gè)月后纬乍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裸卫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年仿贬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墓贿。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茧泪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聋袋,到底是詐尸還是另有隱情队伟,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布幽勒,位于F島的核電站嗜侮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏啥容。R本人自食惡果不足惜锈颗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咪惠。 院中可真熱鬧宜猜,春花似錦、人聲如沸硝逢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)渠鸽。三九已至叫乌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徽缚,已是汗流浹背憨奸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凿试,地道東北人排宰。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像那婉,于是被迫代替她去往敵國(guó)和親板甘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359