Django

djangoのPermissionMixinをserializerで送れた(Total:26day79.5h)

権限管理をフロント側でもしたい

Djangoには、MixinPermissionという権限をテーブルごとに細かく設定する機能があります。
Django側では、has_permissionでコントロールができるのですが、フロント側に送るデータは変えるほどでないけど、権限によって表示するしないをコントロールしたい場合が出てきました。

名前のところにある労働時間の合計と有給取得時間です。
スケジュール作成者は、みんなの時間をみながら調整するので全員のが見れるようにしたくて、スタッフはできれば、見れない方がいいかな。ってのが希望です。

シフトを全部足せば時間はわかるから、できれば程度ということで要望を聞いていました。

DjangoのPermissionsMixinがシリアライザーで送る方法がわからなっかたけどこの記事書いてたら解決できた

今もわからないまんまです。
ここまで書いてふと思ったこと。

ふと思いつてやったら無事にシリアライザーで権限を送ることができました!

class UserDetailSerializer(serializers.ModelSerializer):
    """
    ユーザー詳細シリアライザー
    """
    class Meta:
        model = User
        fields = [
            'username',
            'first_name',
            'last_name',
            'get_full_name',
            'is_superuser',
            'get_user_permissions',
        ]
        
    def get_user_permissions(self, instance):
        return instance.get_user_permissions

フロントエンド側は、とりあえずスーパーユーザーかログインユーザーと同じかで実装…

今、permissionmixinが送れるようになったから、フロントエンド側も処理を変えたいなぁ。って思いながら、現在のコード。

<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import moment from 'moment'
import $api from "@/services/index";

@Component({
  components: {}
})
export default class ScheduleTable extends Vue {
  // get contents() {
  //   return this.$pageContents.Schedule
  // }
  items = []
  today = [moment().format('YYYYMMDD')]
  nextmonth = []
  super_user = ''
  version = ''
  // 初期表示時に呼び込み
  async created() {
    const res = await $api.yearmonth.getSchedule(this.today)
    this.items = res.data
    this.getNextOpenFlag(this.items[0].start_date)
    // this.super_user = this.$store.state.authen.super_user
    console.log(this.items)
    // console.log(this.super_user)
  }
  //前月ボタン処理
  async getLastMonth(date) {
    const res = await $api.yearmonth.getSchedule(moment(date).subtract(1, 'months').format('YYYYMMDD'))
    this.items = res.data
    this.getNextOpenFlag(moment(date).subtract(1, 'months').format('YYYYMMDD'))
  }
  //翌月ボタン処理
  async getNextMonth(date) {
    const res = await $api.yearmonth.getSchedule(moment(date).add(1, 'months').format('YYYYMMDD'))
    this.items = res.data
    this.getNextOpenFlag(moment(date).add(1, 'months'))
  }
  //読込翌月のシフト情報があるかを取得
  async getNextOpenFlag(date) {
    const res = await $api.yearmonth.getNextOpenFlag(moment(date).add(1, 'months').format('YYYYMMDD'))
    this.nextmonth = res.data
  }
  //公開非公開切替
  async getOpenFlagChaenge() {
    const res = await $api.yearmonth.getOpenFlagChaenge(
      this.items[0].year_month_id,
      {
        version: this.items[0].version
      })
    if (res) {
      this.items[0].open_flg = res.data.open_flg
    } else {
      console.log('error')
    }
  }
}
</script>

<template>
  <div v-if="items[0]">
    <v-btn
      class="ma-2"
      color="orange darken-2"
      dark
      @click="getLastMonth(items[0].start_date)"
    >
      <v-icon dark left>mdi-arrow-left</v-icon>
      前月
    </v-btn>
    <v-btn
      class="ma-2"
      color="primary darken-2"
      dark
      @click="getOpenFlagChaenge(items[0].year_month_id, items[0].open_flg)"
    >
      <p v-show="items[0].open_flg==='公'">
        非公開
      </p>
      <p v-show="items[0].open_flg==='未'">
        公開
      </p>
    </v-btn>
    <!-- 翌月のデータがなければ翌月ボタン非表示 -->
    <span v-if="nextmonth.length !==0">
      <v-btn
        class="ma-2"
        color="orange darken-2"
        dark
        @click="getNextMonth(items[0].start_date)"
      >
        <v-icon dark left>mdi-arrow-right</v-icon>
        翌月
      </v-btn>
    </span>
    <!-- 翌月のデータがなければ翌月シフト作成ボタンを表示する -->
    <span v-else>
        <v-btn class="ma-2" color="primary darken-2" dark>翌月シフト作成</v-btn>
    </span>
    <v-simple-table>
      <thead>
        <tr>
          <!-- 日付の期間を表示 -->
          <th>{{ items[0].start_date + '~' + items[0].end_date }}</th>
          <!-- 取得した日付曜日リストを取り出し表示する -->
          <template v-for="item in items">
            <th v-for="dayweek in item.dayweek" :key="dayweek.index">
              <div v-if="dayweek.day_week_display === '土'">
                <span class="sat">
                  {{ dayweek.day }}
                  <br />
                  {{ dayweek.day_week_display }}
                </span>
              </div>
              <div v-else-if="dayweek.day_week_display === '日'">
                <span class="sun">
                  {{ dayweek.day }}
                  <br />
                  {{ dayweek.day_week_display }}
                </span>
              </div>
              <div v-else>
                <span>
                  {{ dayweek.day }}
                  <br />
                  {{ dayweek.day_week_display }}
                </span>
              </div>
            </th>
          </template>
        </tr>
      </thead>
      <tbody v-for="(item, key, index) in items" :key="index">
        <!-- 社員ごとのスケジュールを処理 -->
        <tr v-for="(useryear, index) in item.user_year_month" :key="index">
          <td>
            {{ useryear.user.get_full_name }}
            <!-- スーパーユーザーかログインユーザーとシフト表示者が同じであれば月の合計を表示する-->
            <p v-if="$store.state.authen.super_user===true || $store.state.authen.username===useryear.user.username">
              {{ ' 労' +
              useryear.total_work_time + ' 有' +
              useryear.paid_break_time }}
            </p>
          </td>
          <td v-for="(schedule, index) in useryear.schedule" :key="index">
            <div v-bind:class="schedule.shisetsu1.color">
              {{ schedule.shift1.name }}
            </div>
            <div v-if="schedule.shift2 !== null">
              <div v-bind:class="schedule.shisetsu1.color">
                {{ schedule.shift2.name }}
              </div>
            </div>
            <div v-if="schedule.shift3 !== null">
              <div v-bind:class="schedule.shisetsu1.color">
                {{ schedule.shift3.name }}
              </div>
            </div>
          </td>
        </tr>
      </tbody>
    </v-simple-table>
  </div>
</template>

<style lang="scss" scoped>
.sat {
  text-align: center;
  color: #0d47a1;
}
.sun {
  text-align: center;
  color: #b71c1c;
}
td {
  text-align: center;
}
</style>

138行目に処理を入れています。

これで、スーパーユーザー権限を持っていれば全員の時間が表示されますし、個人でログインしている人は、ログインユーザーの時間がだけ表示されるようになります。

ごろう
やったーできた!

やればできる!時間はかかるけどね(笑)

-Django

© 2022 ごろう@縁紡ぐ