毎日ホテルプロジェクト回顧録

20250 ワード

1.プロジェクト紹介

  • 日常ホテルをテーマにした
  • プロジェクト
  • 開発期間:2021/8/17~2021/8/27
  • 開発者:フロントエンド3名、バックエンド
  • 2名
    住所:https://github.com/wecode-bootcamp-korea/23-2nd-MAEILYHOTEL-backend2
  • ビデオプレゼンテーション:https://www.youtube.com/watch?v=qDQXFb2oayE2
  • 私が担当している機能
    -宿泊先、日付別検索検索検索機能
    -寮の種類別検索機能
    -会員等級変更機能
    -コメント生成機能
  • 宿泊先・日付別検索検索検索機能



    寮の種類別検索機能



    会員レベル変更機能



    コメント機能の作成



    2.価値のあるコード


    最初のプロジェクトで使用したことのないQオブジェクトを使用して、条件によって寮をフィルタリングして照会します.フィルタ条件は以下の3種類で、クエリーパラメータで要求を受け入れます.
    1.地域別
    2.日付(チェックイン、チェックアウト)
    3.寮の種類別

    2-1モデリング

    # stays.models.py
    # 숙소
    class Staytype(models.Model):
        category = models.ForeignKey('Category', on_delete = models.PROTECT)
        name     = models.CharField(max_length = 45)
    
    # 객실 
    class Room(models.Model):
        staytype  = models.ForeignKey('Staytype', on_delete = models.PROTECT)
        name      = models.CharField(max_length = 45)
        quantity  = models.IntegerField()
    
    # books.models.py
    # 예약
    class Book(TimeStampModel):
        user        = models.ForeignKey('users.User', on_delete = models.CASCADE)
        room        = models.ForeignKey('stays.Room', on_delete = models.CASCADE)
        room_option = models.ForeignKey('stays.RoomOption', on_delete = models.CASCADE)
        check_in    = models.DateField()
        check_out   = models.DateField()
        
    日常ホテルは宿泊プラットフォームなので、各客室の在庫管理は行いません.モデリングを行う場合、Roomの対象は客室の種類(例えばスイートルーム、デラックスルーム)であり、quantityフィールドには各客室の総数が含まれている.日常のホテルのこれらの特徴は、日付によるフィルタリングで最も厳しい役割を果たしています.

    2-2各種エラー


    例)Room qunatity = 5input_check_in = 8/1input_check_out = 8/4
    また、Book対象のroom 1号は以下のように予約されています.

    初回アクセス

    Book.objects.filter(check_in = input_check_in, check_out__gte = input_check_out)
    この場合、Book3,4回抜けてしまう場合があります.

    2回目のアクセス


    その結果、Staytypeのオブジェクトを問い合わせる必要があるため、客室在庫管理は日付別に行う必要がある.要求されたチェックインとチェックアウトの日付と、その間の日付をリストします.for文を使用して、各日付がBookのチェックイン勘定の間に属しているかどうかを確認します.
    この方法で異なる日寮の客室在庫を知り、以下のような形式のコーナーを作成しました.しかし、その中で予約可能な寮を濾過する作業では、阻止された.valueはリスト形式であり,リストの長さはそれぞれ異なる.また、要求されたチェックイン日や外出日にかかわらず、客室在庫を知るforドアを使うのは効率的ではないと思います.
    {
      "8/1" : [{"staytype_id" :1, "quantity" : 2},
      	{"staytype_id" :2, "quantity" : 4}],
      "8/2" : [{"staytype_id" :1, "quantity" : 2},
      	{"staytype_id" :3, "quantity" : 3},
        {"staytype_id" :4, "quantity" : 3}]
    }
    ここまで何日かかかりましたが、どのようにアプローチすれば正しいのか分かりません.また、心の中で設定したコードの完成時間は過ぎています.チームプロジェクトなので、時間が限られているので、指導者のアドバイスを得ても、できるだけ早くこの問題を解決しなければなりません.まず、日常会議では、チームメンバーが日付でフィルタリングされたblokerと解決の可能性を共有しました.
    q1 = Q(room__book__check_in__range = [check_in, check_out])
    q2 = Q(room__book__check_out__range = [check_in, check_out])
    q3 = Q(room__book__check_in__lte = check_in, room__book__check_out__gte = check_out)
    第1週の金曜日に指導者の炳民と一緒に様々な場合の濾過方法を考えた.どうして早くいろいろな状況から考えずに、一つの条件だけを考えていたのか...
    1つ目はユリカ!
    remain = Staytype.objects.annotate(Sum('room__quantity') - Count('room__book__id',filter=(q1|q2|q3)))
    日付によってフィルタリングされた後、残りの寮Staytype対象者のうち、空き客室を探す段階に入った.ここでも解決していない問題は、下図のように、客室合計から予約客室数を差し引くと、合計よりも大きな数値が返されることです.まずSumCountにそれぞれコメントを行い、正しい数値が戻ってくることを確認します.
    最終的に一緒に使った時、何かの理由で変な数値が出てきたと思ったので、この部分をグーグル化してみました.Stackoverflowで私と同じ問題を抱えている人が見つかることに気づきました.MySQLでクエリー文に変換するときにJOINを重ねて使うので、Subqueryでこの問題を解決できます.2回はユリカで!
    これで解決しましたが、複数のクエリーセットに対してsubquery returns more than 1 columnというエラーが発生しました.この部分は同じバックグラウンドチームメンバーMinと共有し,それぞれ家で符号化したが,同様の問題を解決した.閔さんは私にOuterRefを使うと、複数のクエリーセットも戻ってくると教えてくれました.したがって、以下のコードを完了することができます.

    2-3完了コード

    # stays.views.py            
    stays = Staytype.objects.filter(q)
    
    total  = stays.annotate(total = Sum('room__quantity')).filter(pk = OuterRef('pk'))
    booked = stays.annotate(booked = Count('room__book__id',filter=(q1|q2|q3))).filter(pk = OuterRef('pk'))
    stays  = stays.annotate(
    	total  = Subquery(total.values('total')),
            booked = Subquery(booked.values('booked')),
            remain = F('total')-F('booked'),
            is_available = Case(
                When(remain = 0), 
                then = False, 
                default = True)
        	).exclude(is_available= False)

    分解後

    # stays.views.py
     stays = Staytype.objects.filter(q).prefetch_related('room_set', 'room_set__book_set').annotate(
                    total_room_count = Sum('room__quantity'), 
                    booked_room_count = Subquery(
                        Staytype.objects.annotate(booked_count = Count('room__book__id', filter = (q1|q2|q3))).filter(pk = OuterRef('pk')).values('booked_count')
                        ), 
                        is_available = Case(
                            When(total_room_count__gt = F('booked_room_count'), then = True), 
                            default = False
                        )
                ).exclude(is_available = False) 
    このコードに価値があるのは、機能が実現したからだけではないと思います.「週末までこのコードを完成させたので、パンツで同じ問題についてもアプローチ方法と関連資料を共有しました」.ここまで言って解決すれば、この部分が詰まっていて、「この方法で大丈夫」のように、問題解決のために一緒に頑張りました.コードが完成して喜びを感じました.このコードはチームメンバーと一緒に完成したと思います.このとき,共有の過程で,開発者たちの共有文化を感じたようである.

    3.学習の連続性


    最初のプロジェクトでコミュニケーションの重要性を感じたとすれば、2番目のプロジェクトでは学習の継続です.機能と論理の難易度が高まり、Subquery、Case、Whenなどのドラムの新しい概念を熟知することができます.画像ファイルをアップロードするためにs 3を紹介しdockerも作成しました.
    隊員たちもたくさんのことを学んだ.
    PM東雨は初日から私たちにどう行けばいいか指導してくれました.また、バックグラウンドでソーシャルログイン機能を実施するのが1位のときは、すぐに転向して、一緒に1位にランクインします.この時の東雨のリーダーシップはまぶしい
    明成はチームメートの世話をよくしてくれて、いつも雰囲気をよくしてくれました.
    朱英は疲れているかもしれない状況でも自分の仕事を続けた.
    ミン氏とは、それぞれの機能だけを表現するのではなく、お互いのコードを共有する.自分のことだけで忙しいかもしれない状況でも、一緒にやる時間が必要です.
    1、2次種目の疲労蓄積やスキルの難易度が高くなるにつれて、全員が疲れている場合でも、お互いに気を遣う心があるので、うまく仕上げることができます.ユーモラスで楽しいチームプロジェクトで締めくくります.