스쿼드 모델링 (MongoDB ArrayField)

KHoney·2022년 7월 19일
0

futqualizer

목록 보기
5/8

각 유저는 스쿼드를 생성하고, 이를 관리할 수 있어야한다.

스쿼드는 크게 포메이션 별로 나누어지고, 각각의 포지션마다 선수들을 세울 수 있어야 할것이다.

따라서 스쿼드는 다음과 같은 데이터를 갖고 있어야한다.

  • 생성한 유저
  • 포메이션
  • 선수단 : [
    { position : 포지션, 선수 : Player }, …
    ]

MongoDB 에서는 배열 데이터를 지원하기 때문에 선수단, players 를 쉽게 구현할 수 있을 것이다.

일단 squad 앱을 생성하고 시작한다.

django-admin startapp squad

포메이션, 포지션의 종류는 정해져있기 때문에 Enum 타입으로 생성한다.

#squad/models.py

from djongo import models
class Position(models.Choices):
    GK = "GK"
    LB = "LB"
    LWB = "LWB"
    LM = "LM"
    LW = "LW"
    CB = "CB"
    RB = "RB"
    RWB = "RWB"
    RM = "RM"
    RW = "RW"
    CDM = "CDM"
    CM = "CM"
    CAM = "CAM"
    CF = "CF"
    ST = "ST"   

class Formation(models.TextChoices):
    F442 = "4-4-2"
    F433 = "4-3-3"
    F41212 = "4-1-2-1-2"
    F352 = "3-5-2"
		...

스쿼드는 최종적으로 Player 와 포지션이 매핑 되어있는 배열을 가져야 하기 때문에, 각각의 값을 가지고있는 class 를 정의한다.

#squad/models.py
class player_in_sqaud(models.Model):
		#enum 으로 선언한 Position 값을 갖도록한다.
    position = models.CharField(choices=Position.choices, default=Position.ST, max_length=5,null=False)
    playerId = models.PositiveIntegerField(null=False,default=0)

    class Meta:		# 실질적으로 DB 에 값이 들어갈 필요가 없기 때문에 추상으로 선언한다.
        abstract = True

MongoDB 에 저장될때 배열의 값이 Document 형식으로 저장되기 때문에, 이를 변형시켜 줄 From 을 정의 한다.

#squad/models.py
class Player_Position_Form(forms.ModelForm):
    class Meta:
        model = player_in_sqaud
        fields = (
            'position', 'playerId'
        )

최종적으로 Squad 의 Model 을 정의한다.

#squad/models.py
class Squad(models.Model):		
    name = models.CharField(max_length=20,default='My Squad')
    own_user = models.ForeignKey(User, on_delete=models.CASCADE)		# 스쿼드 소유자
    formation = models.CharField(choices=Formation.choices, default=Formation.F442,max_length=20) # enum 으로 선언한 포메이션		
    players = models.ArrayField(
        model_container=player_in_sqaud, #값을 가질 객체
        model_form_class=Player_Position_Form, #객체의 From
        default=list()
    )
    objects = models.DjongoManager()
⚠️ 이제 Migration 을 하고 저장, 호출하는 로직을 실행하면 된다…

고 생각했는데, 저장은 정상작동하는데 호출, Squad.objects.* 이 정상작동하지 않는다.
Abstract models cannot be instantiated for models for retrieving data
에러가 발생한다.**

검색해보니, Django 와 djongo 버전이 맞지 않아서 발생하는 문제다.

Django 4.0.6 버전을 사용하고 있었는데, 3.1.12 로 변경한다.

pip uninstall django

pip install django==3.1.12

외부 라이브러리를 많이 사용하다 보니 생각보다 버전에 따른 호환 문제가 자주 발생하는 것 같다.

Djongo 의 ArrayFiled 를 사용하는 방법은
Using Djongo Array Model Field - Djongo (djongomapper.com) 를 참고하였다.

profile
좋은 개발자가 되고싶은

0개의 댓글