한국어로 옮기기 어색한 단어들은 영문으로 혹은 해석이 애매한 구절은 직역한 그대로 사용 하였습니다.
필드 이름 제한사항들
장고는 모델 필드 이름에 몇가지 제한 사항들이 있다.
1.필드이름으로 파이썬 예약어가 될 수 없다.파이썬 에러를 발생 시킬 수 있기 때문이다. 예를들면:
xxxxxxxxxx
class Example(models.Model):
pass = models.IntegerField() # 'pass' is a reserved word!
2.필드이름에 underscore('_') 2개 이상 포함할 수 없다. 장고의 쿼리 룩업 문법 동작 때문이다 예를들면:
x
class Example(models.Model):
foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
3.필드이름은 underscore('_') 로 끝나면 안된다 이유는 위의 이유와 비슷하다
필드 이름은 데이터베이스 컬럼의 이름과 반드시 일치할 필요는 없기 때문에 이러한 제한 사들은 해결될 수 있다. db_column option을 보자
join
, where
or select
같은 SQL 예약어는 모델 필드 이름으로 허용된다. 장고가 모든 SQL 쿼리 마다 모든 데이터베이스 테이블 이름과 컬럼 이름을 이스케이프 하기 때문이다. 특정 데이터 베이스 엔진의 인용 구문을 사용한다
내 마음대로 해설
실제로 위의 제한사항들을 실행해 보았다.
1.makemigration 시 파이썬 문법 에러가 발생한다.
xxxxxxxxxx
(py38) ➜ src python manage.py makemigrations
...
File "/Users/thkwon/workspace/dev/test-drf/src/thkwon_lab/models.py", line 4
pass = models.IntegerField()
^
SyntaxError: invalid syntax
2.makemigration 시 에러가 발생한다.
xxxxxxxxxx
(py38) ➜ src python manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
thkwon_lab.Example.foo__bar: (fields.E002) Field names must not contain "__".
3.makemigration 시 에러가 발생한다.
xxxxxxxxxx
from django.db import models
class Example(models.Model):
test_ = models.IntegerField()
xxxxxxxxxx
(py38) ➜ src python manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
thkwon_lab.Example.test_: (fields.E001) Field names must not end with an underscore.
결론적으로 위 제한 사항에 대해서 잘 모르더라도, makemigrations 하는 순간에 에러를 잡아주기 때문에, 위의 내용은 상식적이긴 하지만, 참고로만 알고 있어도 될 것 같다.
번외
x`join`, `where` or `select` 같은 SQL 예약어는 모델 필드 이름으로 허용된다. 장고가 모든 SQL 쿼리 마다 모든 데이터베이스 테이블 이름과 컬럼 이름을 이스케이프 하기 때문이다. 특정 데이터 베이스 엔진의 인용 구문을 사용한다
이 문장이 잘 이해가 되지 않았다. 관련해서 설명해놓은 다른 블로그 혹은 스택오버플로우 글도 찾지 못하였다. 그래서 따로 실험을 해보았다.
x
from django.db import models
class Example(models.Model):
where = models.CharField(max_length=100)
class Meta:
db_table = "example"
where
를 필드 이름으로 가지는 모델 클래스를 만든다. 그리고 값을 넣고 쿼리가 어떻게 나오는지를 살펴본다
x
In [1]: Example.objects.create(where='some_where')
INSERT INTO "example" ("where")
VALUES ('some_where')
Execution time: 0.001440s [Database: default]
Out[1]: <Example: Example object (3)>
In [2]: Example.objects.filter(where='some_where')
Out[2]: SELECT "example"."id",
"example"."where"
FROM "example"
WHERE "example"."where" = 'some_where'
LIMIT 21
Execution time: 0.000224s [Database: default]
<QuerySet [<Example: Example object (2)>, <Example: Example object (3)>]>
위에서 확인한 바와 같이 실행하는 것에는 크게 문제가 없음을 볼 수 있다. SQL 예약어들의 경우 대문자로 표시되고 있어서, 크게 헷갈리지도 않는 느낌이기도 하다. 그러나 개인적인 생각으로 어찌되었던.. 이름이 겹치면 헷갈리기 마련이기 때문에 장고에서 허용한다고 하더라도, 위와 같이 예약어 이름과 겹치게 쓰는 일은 없도록 하는게 맞을 것 같다.
이와 별개로 모든 SQL 쿼리 마다 모든 데이터베이스 테이블 이름과 컬럼 이름을 이스케이프 하기 때문이다. 특정 데이터 베이스 엔진의 인용 구문을 사용한다
의 명확한 근거는 문서나 웹상에서는 찾을 수 없었고, 코드에서 찾아야할듯 하다 이 부분은 나중에 발견하는대로 블로깅을 따로 할 예정이다.
'개발 > 장고' 카테고리의 다른 글
[해설과 함께 읽는 Django 문서] Model methods (0) | 2021.04.04 |
---|---|
[해설과 함께 읽는 Django 문서] Models - Meta Options, Model 속성들 (0) | 2021.02.02 |
[해설과 함께 읽는 Django 문서] Models - 파일 간 모델 (0) | 2021.01.31 |
[해설과 함께 읽는 Django 문서] Models - 일대일 관계 (0) | 2021.01.31 |
[DRF] Serializers - 객체 역직렬화 하기 (0) | 2021.01.31 |