MA(q) 모델에서 ACF(t>q)가 0이 되는 이유
왜 ACF가 MA를 설명하는지 아무리 찾아도 모르겠다... ACF(k)가 lag=k에서 랑 의 직간접 상관을 의미하는 거랑 MA가 에서 이전 오차를 반영하는 거랑 무슨 상관인건데... ACF가 차분한 다음에 계산한 것도 아니잖아? SARIMAX까지 갈 길이 멀다
Django 플젝에서 secret code 파일을 따로 만들어 gitignore에 넣으려다가 여러 문제가 생겨서... 처음부터 플젝 다시 만들었다 😂 나중에 문제 생기느니 지금 해야지
pipenv --three
로 다시 버블 만드려는데 아래 에러가 나오면 다음 스텝으로 해결한다.
pipenv system is intended to be used for pre-existing Pipfile installation, not installation of specific packages.
pipenv --uninstall all
pipenv 관련 패키지 모두 삭제pipenv --three
시도pipenv --unsinstall all
을 다시 실행하고pip uninstall virtualenv
, pip uninstall virtualenv-clone
가상환경 세팅 지우고pip uninstall pipenv
pipenv 제거하고pip install pipenv
pipenv 다시 설치pipenv 작업을 했던 폴더를 그냥 삭제한 후 똑같은 이름의 폴더를 다시 만들어서 pipenv --three
를 하니까 저런 에러가 있었다. 실험을 해보지 못해서 같은 이름의 폴더가 문제였던 건지는 확인하지 못했지만(그냥 pipenv로 이것저것 하다 생긴 오류였을지도) 우선 저렇게 해결했다!
어제 에러를 다 고친 줄 알고 기뻐했는데... pipenv를 다시 설치하고 pipenv --three
로 Python 버전을 세팅하자 Pipfile이 다른 폴더에 생겼다😱
Virtualenv location: C:\Users\username\.virtualenvs\username-hFtWgrld
플젝 폴더가 아니라 저 폴더 안에 .virtualenvs, Pipfile, Pipfile.lock이 생겼다. 그래서 pipenv shell
을 실행하면 자동으로 저 폴더로 이동해버렸다.
찾아보니 Pipfile이 다른 폴더에 생기는 게 오류는 아니라고 한다(.virtualenvs 안에 내 프로젝트명이 생기는 걸로 봐서 플젝에서 작동 안 하는 건 아닌 것 같다).
그래도 나는 플젝 폴더 안에 생기는 게 마음이 편할 것 같아서 해결책을 찾았다. 방법은 간단하다.
set PIPENV_VENV_IN_PROJECT="enabled" # window 기준
export PIPENV_VENV_IN_PROJECT="enabled" # mac 기준
이렇게 설정해주고 다시 pipenv --three
를 하면 Pipfile이 플젝 폴더 안에 들어가있다!
데이터 유형이 바뀌면 migration을 생성하고 그에 맞추어 DB를 업데이트하는 과정을 말한다. (데이터 유형 ≃ 데이터 제약 조건으로 봐도 되는 듯)
models.py
안에 데이터 유형을 입력한 후 python manage.py makemigrations
을 실행하면 migration
이 생성된다. 그리고 python manage.py migrate
를 실행하면 migration
에 맞추어 데이터 유형이 DB에 적용된다.
framework가 library보다 훨씬 강한 규칙을 가진다. Django(framework)에서는 모든 파일/폴더/데이터 명칭 등등의 규칙을 원래 상태 그대로 따라야 한다. 대신 새로운 것을 만드는 것은 괜찮다.
users
앱을 생성한다.django-admin startapp users
models.py
에서 원하는 형식으로 DB 필드를 편집한다. 필드 유형은 Django 문서에서 선택한다. (modles.py
에 입력한 코드를 ORM(Object Relational Mapper)가 SQL문으로 바꿔서 데이터베이스를 생성한다.)default=채우려는 기본값
혹은 null=True
등의 옵션을 준다. 후자는 기존 레코드의 새 필드 값을 null로 두는 것이다. from ast import Pass
from django.db import models
from django.contrib.auth.models import AbstractUser
# AbstractUser 클래스를 상속하여 User 클래스를 만든다.
class User(AbstractUser):
# 원하는 필드를 적절히 수정한다.
bio = models.TextField(default="")
settings.py
에서 앱을 추가한다. 기본 세팅은 INSTALLED_APPS = [...]
형식으로 되어있는데, 기본 세팅과 내가 만든 앱을 구분하고 싶으면 이런 식으로 써도 된다.DJANGO_APSS = [
# 기존 INSTALLED_APPS에 들어있던 APP 리스트 넣기
]
PROJECT_APPS = [
# 내가 만든 APP 리스트 넣기
'users.apps.UsersConfig',
]
INSTALLED_APPS = DJANGO_APSS + PROJECT_APPS
settings.py
에서 USER을 덮어씌운다. Django 문서는 유저를 커스터마이징할 때 위 파일에서 AUTH_USER_MODEL=
을 이용해 덮어씌우라고 설명한다.users
앱의 models.py
에서 User
라는 새로운 클래스를 만들었으니까 아래와 같이 설정한다.AUTH_USER_MODEL = 'users.User'
db.sqlite3
를 지운다.python manage.py makemigrations
를 실행해서 migration 파일(users\migrations\0001_initial.py
)을 만들고,python manage.py migrate
을 실행해서 migrate을 한다. 그러면 다시 db.sqlite3
가 생성된다.python manage.py runserver
하면 내가 만든 앱 DB에 맞게 서버가 작동한다!가끔 파이썬에서 함수나 클래스를 새로 선언하면 자동으로 """ """
가 나오는 경우가 있다. 이걸 docstring이라고 하는데 그 안에 들어있는 문자열(보통은 설명문)을 별개의 객체로 처리해준다. 모듈 import 등을 할 때 설명을 편리하게 확인할 수 있다. 자세한 내용은 이 글 참고.
위에서 특정 필드의 값에 null을 허용하려면 null=True
로 두면 된다고 했다. 하지만 admin 패널에서 입력폼(form)에 아무것도 넣지 않은 채 저장하려면 해당 필드를 입력하라는 경고가 나온다. 이는 DB 유효성 검사와 폼의 유효성 검사가 별개이기 때문이다. null=True
는 입력폼 내 필수 입력필드가 빈 칸으로 제출하는 걸 허용하지 않는다. 이 경우에는 따로 blank=True
를 주어야 한다.
CharField, TextField는 null=True를 쓰지 말자!
장고는 두 문자 필드에 대해서 빈 값(null)을 ""로 두기 때문에null=True
옵션을 줄 필요가 없다. 만약 위 옵션을 주면 빈 값을 처리하는 방법이 ""와 null 두 가지가 되기 때문에 에러가 날 수 있다. 출처: 스택오퍼플로우 답변
모델을 admin에서 관리하게 만들 수 있다. 위에서 만든 users
의 모델을 admin에 등록하는 과정은 다음과 같다.
users
앱 내의 admin.py
파일을 편집한다.from . import models
@admin.register(models.User) # <- decorator
class CustomUserAdmin(admin.ModelAdmin):
pass
한 번에 여러 모델을 등록할 수도 있다.
@admin.register(models.RoomType, models.Facility, models.Amenity, models.HouseRule) class ItemAdmin(admin.ModelAdmin): pass
models.User
클래스를 등록하라"는 뜻이다. admin.ModelAdmin
은 admin.py
에 들어있는 클래스로, 원래의 admin 패널 설정이 들어가있다.useres
모델 중 어느 필드를 노출할지/필터를 걸지/수정 가능하게 할 지... 등등을 설정할 수 있다. 가능한 옵션은 공식 문서에서 확인 가능.list_display
) 필드 혹은 필터를 걸(list_filter
) 필드를 설정할 수 있다.@admin.register(models.User)
class CustomUserAdmin(admin.ModelAdmin):
"""
Custom User Admin
"""
list_display = ("username", "gender", "language", "currency", "superhost")
list_filter = ("superhost", "language", "currency")
상속을 이용해서 여러 앱에서 공통으로 사용하는 필드를 한 번에 선언할 수 있다. created
필드가 '게시글', '댓글' 앱 모두에 사용하는 경우를 예시로 들어보자.
created
필드를 선언하기 위한 임의의 앱 core을 생성한다. (django-admin startapp core
)models.py
에 아래와 같이 필드를 선언한다.class TimeStampedModel(models.Model):
"""Time Stamped Model"""
created = models.DateTimeField()
models.py
를 따로 데이터베이스로 만들고 싶지 않다. 위에서 만든 필드에 아래와 같이 선언하면 된다.class TimeStampedModel(models.Model):
"""Time Stamped Model"""
created = models.DateTimeField()
class Meta:
abstarct = True # 데이터베이스를 만들지 않는 옵션
config
>settings.py
에 등록한다.PROJECT_APPS = [
"core.apps.CoreConfig",
...]
models.py
에서 상속해서 사용할 수 있다.from django.db import models
from core import models as core_models # core 앱 내 모델 상속
# Create your models here.
class Room(core_models.TimeStampedModel):
"""Room Model Definition"""
pass
__str__
객체의 내용을 문자열로 가공해서 보여줄 때 사용하는 함수. 이 글에 설명이 잘 나와있다.
예를 들어 Human
클래스와 Soo
인스턴스를 아래처럼 만들었다고 가정해보자.
>>> class Human():
def __init__(self, name):
self.name = name
>>> Soo = Human('Soo')
여기서 print(Soo)
를 하면 <__main__.Human object at 0x00000...>
이런 식으로 메모리 주소가 나온다. 메모리 주소 대신 다른 정보를 문자열 형태로 전달하려면 Human
클래스 내부에서 __str__
함수를 사용하면 된다.
class Human():
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
이제 print(Soo)
를 하면 Soo
가 출력된다!
def __str__(self): return 'something'
을 하면 어떤 인스턴스가 생성되더라도 무조건something
문자열만 반환한다. 이럴 일은 없겠지만 반드시 인스턴스의 정보를 사용할 필요는 없다는 걸 보여주기 위해 든 예시!
장고 내 테이블(DB)는 다른 테이블과 relation을 가질 수 있다. 일대다는 ForeignKey
, 다대다는 ManyToManyField
로 설정한다. 예를 들어 User 테이블(1)-Room 테이블(N), Room type 테이블(N)-Room 테이블(M)의 관계가 있다고 가정하자.
이 때 Room의 models.py
에서 아래와 같이 관계를 설정할 수 있다.
from users import models as user_models # 연결하려는 테이블 가져오기
from roomtype import models as roomtype_models
class Room(core_models.TimeStampedModel):
host = models.ForeignKey(user_models.User, on_delete=models.CASCADE)
room_type = models.ManyToManyField(roomtype_models, blank=True)
이렇게 하면 Room 테이블의 host
필드는 User 테이블 내의 모델(레코드)을 FK로 가진다.
ForeignKey
에서 사용하는 파라미터는... 이어서 알아보자
ForeignKey
파라미터한 테이블에서 모델이 사라졌을 때, 그 테이블의 모델을 ForeignKey
(일대다 관계)로 가지는 다른 테이블에서 어떻게 처리할지 설정하는 파라미터이다.
CASCADE
models.CASCADE
는 폭포수가 떨어지듯이(cascade) 모델이 사라지는 효과가 다른 곳에도 적용된다는 의미이다. 즉 User 테이블의 특정 모델을 삭제하면, 그 모델에 연결된 Room 테이블의 모델도 함께 삭제된다.PROTECT
models.PROTECT
는 User의 모델이 다른 테이블의 FK로 들어가있다면 그 User 모델을 곧바로 삭제할 수 없게 제한한다. 다른 테이블의 FK를 삭제한 후에야 User 모델을 지울 수 있다.SET_NULL', 'SET_DEFAULT
models.SET_NULL
은 User 모델을 지우면 다른 테이블의 FK를 NULL 처리 한다. models.SET_DEFAULT
는 NULL 대신 FK를 따로 설정한 default 값으로 처리한다.admin 패널에서 모델의 값을 수정하려면(Users 모델에 user을 추가했듯이) 다음과 같이 admin.py
에 모델을 추가해야 한다.
@admin.register(models.Model1, models.Model2) # , 를 이용해서 한 번에 여러 모델을 등록할 수도 있다.
class RoomAdmin(admin.ModelAdmin):
이렇게 등록하면 admin 패널에서 모델 명칭은 '모델명'+'s'와 같이 나온다. 예를 들어 위의 경우에는 'Model1s', 'Model2s'로 나온다.
만약 다른 명칭을 원한다면 class Meta
에서 verbose_name_plural
을 설정해야 한다(앞에서 abstract = True
을 썼던 그 Meta
이다).
class Model1():
class Meta:
verbose_name_plural = "First Models"
's'를 붙이는 것은 유지하되 다른 명칭으로 쓰고 싶으면 verbose_name
을 설정한다. 예를 들어 RoomType 모델은 'Room types'로 나오는데, 이걸 'Room Types'으로 바꾸고 싶으면 아래와 같이 쓴다.
class RoomType():
class Meta:
verbose_name = "Room Type"