본문 바로가기

Frame Work/Django

[Django] model 필드 순서 조정하기

728x90
반응형

 

 

 

개요

AbstractBaseUser 모델을 통해 db에 migrate까지 했으나 막상 DataBase에 들어가서 직접 테이블 관찰해 보니 필드 순서가 엉망입니다. 

 

 

필드의 순서를 왜 조정해야 될까?

사실 필드의 순서가 엉망이라고 해서 개발이 안 된다거나 해당 필드를 참조할 수 없다거나 하는 에러가 발생하진 않습니다. 개인적인 생각은 필드의 순서를 조정한다는 것의 의미는 필요한 정보를 먼저 보겠다라는 의도지 않을까 싶습니다.

 

예를 들어 DB에 접속해서 직접 데이터를 고쳐야 하는 상황에서  한 스키마의 필드가 20개가 넘는다면 매번 필요한 데이터를 찾는데 스크롤을 끝으로 미뤄서 확인하는 수고를 들여야 합니다.

 

마치 생성일이 섞인 A4 용지에서 필요한 데이터를 찾는 것과 동일하지 않을까 합니다.

 

 

왜 순서가 꼬일까?

AbstactBaseUser 모델을 예로 들어보자면 다음과 같이 PermissionMix과 AbstractBaseUser를 상속해야 됩니다.

class User(AbstractBaseUser, PermissionsMixin):
	...

하지만 AbstractBaseUser와 PermissionMixin 내부 구현을 보게 되면 다음과 같이 Attribute가 선언되어있음을 알 수 있습니다.

class AbstractBaseUser(models.Model):
    password = models.CharField(...)
    last_login = models.DateTimeField(...)

    is_active = True
  	...
    
 class PermissionsMixin(models.Model):
    """
    Add the fields and methods necessary to support the Group and Permission
    models using the ModelBackend.
    """
    is_superuser = models.BooleanField(...)
    groups = models.ManyToManyField(...)
    ...
MRO에 따라 왼쪽에서 오른쪽으로 해석이 먼저 되기 떄문에 다음과 같은 순서로 필드가 조정될 것입니다.
password = models.CharField(...)
last_login = models.DateTimeField(...)
is_active = True
is_superuser = models.BooleanField(...)
groups = models.ManyToManyField(...)
즉 User에 관해 추가로 정의하는 필드는 위의 필드가 모두 정의되고 난 다음 추가로 정의되는 순서를 가지게 됩니다.
 

Migrate 전, 생성 순서 조정하기

필드가 생성되는 순서를 조정하는 방법에는 두 가지가 있습니다.

  1. migration 파일에서 순서를 조정하기.
  2. 상속한 객체의 필드를 override 

첫 번째 방법인 migration 파일에서 순서를 조정하는 것은  `python manage.py makemigratons`의 결과로 나오는 파일에서 순서를 직접 조정해주는 방법입니다. 이 파일의 내용은 다음과 같을 것이고

...
	operations = [
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('user_id', models.CharField(max_length=12, unique=True, verbose_name='userid')),
				...
            ],
...

fields를 정의하는 리스트에서 직접 위치를 바꿔주고 난 후 migrate를 하면 변경된 후의 필드의 순서가 적용됩니다.

 

두 번째 방법인 상속한 객체의 필드를 직접 오버라이드 하는 것은 상속된 객체의 내부 속성을 파악한 뒤 아래와 같이 직접 순서를 정의해주는 방법입니다.

class User(AbstractBaseUser, PermissionsMixin):
    # 직접 정의한 필드
	user_id = models.CharField(...)
	
    # 오버라이딩한 필드
    password = models.CharField(...)
    last_login = models.DateTimeField(...)
    is_superuser = models.BooleanField(...)
    groups = models.ManyToManyField(...)
 

Migrate 후, 필드의 순서를 바꿔주기

이 부분은 확실한 것은 아니지만 저는 다음과 같은 방법을 사용했습니다.

python manage.py migrate APP_NAME zero

위 명령을 실행하면 마이그레이션 내역을 되돌립니다. migrations 디렉터리에 위치한 내역은 다시 migrate를 하게 되면 001부터 시작하게 될 것이고 이때 필드 순서를 조정하고 싶은 migrations 파일에 들어가 순서를 바꿔준 다음 migrate 해줬습니다.

python manage.py migrate APP_NAME

 

728x90
반응형

'Frame Work > Django' 카테고리의 다른 글

[Django] Session !  (0) 2022.05.06
[Django] Select && Prefetch Related !  (0) 2022.02.20
[Django] model migration 꼬였을 때  (0) 2021.09.18
[Django] app의 model만 관리하는 app을 만들어보자  (3) 2021.09.16
django, ForeignKey N+1  (1) 2021.08.16