2014. 9. 18. 11:49ㆍ개발일기/SCM
회사에서 프로젝트로 진행한 SCM(Supply Chain Management)에 대한 개발 이력을 남기려고 한다.
개발 환경은 python + Django로 진행하였다.
여러 APP으로 분류
Django에서는 하나의 프로젝트 안에 여러개의 앱을 등록시킬 수가 있다.
해서 성격이 다른 앱들은 따로 분류하여 프로젝트를 구성하였다.
>> python manage.py startapp test1
>> python manage.py startapp test2
>> python manage.py startapp test3
위와 같은 방식으로 앱을 생성하였고 settings.py 파일에 생성된 해당 앱들을 등록하였다.
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
.....,
'test1',
'test2',
'test3',
)
DB Schema 가져오기
대부분의 장고에서는 models.py에서 DB 스키마를 정한 후에 syncdb 명령을 통해 DB를 생성한다.
하지만 이미 생성되어진 DB Schema를 가져와야 하는 경우도 있는데, 이런 경우에는 아래와 같은 명령어를 사용하였다.
>> python manage.py inspectdb > dbschema.txt
dbschema.txt 파일에는 DB 스키마 정보가 저장되어 있으며, 해당 내용을 적당히 변경하여 models.py에 입력하면 된다.
Settings.py 변경
USE_TZ = False
Django에서 지원하는 Timezone을 사용할 경우에는 datetime.datetime 함수 사용시 에러를 리턴한다.
정확한 이유는 잘 모르겠음...
그래서 일단 Timezone은 사용하지 않는 것으로 변경함.
CsrfViewMiddleware 주석 처리
csrf(Cross Site Request Forgeries) attack은 일반적으로 스크립트 등을 통해 사용자 브라우저에서 악의적인 행동을 하는 것을 말하는데, Django에서는 이를 막아주는 미들웨어를 제공하고 있다.
하지만 CsrfViewMiddleware를 사용할 시, cross-domain 문제가 발생해서 일단은 해당 csrf 미들웨어를 주석처리 함.
urls에서 마지막 슬러시 처리 여부 고민
Django url의 대부분은 마지막에 / 처리로 끝을 나타낸다.
하지만 사용자의 경우 마지막에 /를 기입하지 않는 사용자도 있다.
/를 기입하지 않아도 해당 api가 호출이 되긴 하지만 내부적으로 해당 url을 다시 한번 찾는 과정을 거치는 것 같다.
/ 처리는 나중에 시간이 날때 한번 찾아보기로 함.
(혹시 아시는 분 있으면 답변 부탁드립니다~)
django 관리 페이지에서 display 설정과 search_field 설정
django 관리 페이지에 보면 간혹 foriegn_key로 묶여 있는 경우에는 그냥 object라고만 표시된다.
(object라고 표시되면 보는 사람은 이게 몬지 전혀 알지 못하지요..)
해당 foreign_key class에 가서 def __unicode__를 정의해주면 정의해 준대로 표시가 된다.
class Test-foreign(models.Model):
id = models.IntegerField(primary_key=True)
name = models.ForeignKey('Test-obj', db_column='name')
class Test-obj(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(unique=True, max_length=15, blank=True)
def __unicode__(self):
return "%s" %(self.name)
Search field도 설정할 수가 있다.
Search field는 Model의 Admin에다 정의해야 하는데 admin 정의하는 방법은 요기 클릭..
해당 admin class에 아래와 같이 정의하면 관리페이지에서 해당 field를 검색할 수가 있게 된다.
class Test(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=15)
company = models.CharField(max_length = 30)
class TestAdmin(admin.ModelAdmin):
list_display = ["id", "name", "company"]
search_fields = ["name", "company"]
Django rest framework 사용
Django에서는 rest api 형태의 개발을 좀 더 쉽게 돕기 위해 rest framework라는 컴포넌트를 가지고 있었다.
(기본은 아님)
Django REST framework 웹 페이지 가기
pip를 통해 djangorestframework, markdown, django-filter를 설치한다.
>> pip install djangorestframework
>> pip install markdown
>> pip install django-filter
설치 후에는 settings.py의 INSTALLED_APPS 부분에 'rest_framework'를 추가한다.
INSTALLED_APPS = (
...
'rest_framework',
)
REST framework Exception 사용하기
Settings.py 파일에 ExceptionHandler를 기재함.
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'my_project.utils.custom_exception_handler',
}
Custom exception handler를 만든다. Settings.py에 기입한 utils.py 파일에 custom_exception_handler라는 exception handler를 만든다.
from rest_framework.views import exception_handler
def custom_exception_handler(exc):
response = exception_handler(exc)
if response is not None:
response.data['status_code'] = response.status_code
return response
위의 코드는 raise를 통해 발생한 모든 exception에서 공통적으로 처리되는 루틴으로 해당 response의 status_code를 가져와서 response.data 코드에 심어주는 역할을 하고 있다.
그럼 이제 rest framework에서 지원하는 exception이 있을테고, 스스로 정의한 custom exception이 있을 것이다.
스스로 Exception을 정의했을 때는 어떤식으로 해야하는지 알아본다.
from rest_framework.exceptions import APIException
class ServiceUnavailable(APIException):
status_code = 503
default_detail = 'Service temporarily unavailable'
Custom Exception을 처리하기 위해서는 subclass로 APIException이 필요하고, class내에 property로 status_code와 default_detail이 필요하다.
해당 Exception을 발생하고 싶을 경우에는 코드상에서 아래와 같이 try ~ except로 발생시키거나 raise를 직접호출 하면 된다.
try:
...
except ServiceUnavailable:
raise ServiceUnavailable
rest framework에서 지원하는 Exception은 Django rest Framework 홈페이지를 통해 확인할 수 있다.
2번째 시리즈에서는 transaction과 pagination, filter 등에 대해서 작성하겠습니다.