도저히 django-cors-headers 가 설치 되지 않아서 미들웨어로 처리 했다. (이유는 아직도 모른다.)

 

from django import http

try:
    import settings
    XS_SHARING_ALLOWED_ORIGINS = settings.XS_SHARING_ALLOWED_ORIGINS
    XS_SHARING_ALLOWED_METHODS = settings.XS_SHARING_ALLOWED_METHODS
    XS_SHARING_ALLOWED_HEADERS = settings.XS_SHARING_ALLOWED_HEADERS
except:
    XS_SHARING_ALLOWED_ORIGINS = ''
    XS_SHARING_ALLOWED_METHODS = ['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE']
    XS_SHARING_ALLOWED_HEADERS = []


class XsSharing(object):
    def __init__(self, get_response=None) -> None:
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_request(self, request):

        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = http.HttpResponse()
            response['Access-Control-Allow-Origin'] = XS_SHARING_ALLOWED_ORIGINS
            response['Access-Control-Allow-Methods'] = ",".join(XS_SHARING_ALLOWED_METHODS)
            response['Access-Control-Allow-Headers'] = ",".join(XS_SHARING_ALLOWED_HEADERS)
            return response

        return None

    def process_response(self, request, response):
        if response.has_header('Access-Control-Allow-Origin'):
            return response

        response['Access-Control-Allow-Origin'] = XS_SHARING_ALLOWED_ORIGINS
        response['Access-Control-Allow-Methods'] = ",".join(XS_SHARING_ALLOWED_METHODS)

        return response

 

settings.py에 위의 미들웨어를 선언해준다. 

MIDDLEWARE = [
    'middlewares.middleware.django-crossdomainxhr-middleware.XsSharing',
    ....
]

 

디폴트로 모두 허용이므로 settings.py에 파라미터를 추가해준다.

XS_SHARING_ALLOWED_ORIGINS = '*' # 허용하는 도메인 콤마(,)로 구분 ex: www.google.com, *.naver.com
XS_SHARING_ALLOWED_METHODS = "POST, GET, OPTIONS, PUT, DELETE"

 

 

참고: https://gist.github.com/jessykate/2941258


WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret

로컬과 실서버의 디비의  migrate가 꼬여서 개발한 컬럼이 반영이 안될때!!

컬럼은 처음부터 소스에 반영이 아닌 8번에서 반영되어야 합니다!! (git으로 잠시 stash로 넣어놨다가 8번에서 꺼내세요)

 

  1. 해당 디비의 django_migrations 테이블 데이터 삭제 (truncate)

  2. python3 manage.py makemigrations

  3. python3 manage.py showmigrations

  4. python3 manage.py migrate --fake components ( "django_content_type" 에 name 이 없다고 에러가 나면 하단을 참조하세요.)

  5. 마이그레이션 파일 삭제

    1. find . -path "*/migrations/*.py" -not -name "__init__.py" -delete

    2. find . -path "*/migrations/*.pyc" -delete

  6. python manage.py makemigrations

  7. python manage.py migrate --fake-initial

  8. 변경할 칼럼 반영 

  9. python manage.py makemigrations

  10. python manage.py migrate --fake-initial

 

Good Luck !!

 

 

 

만일!! django_content_type의 name이 없다고 에러가 발생 한다면!!

django.db.utils.ProgrammingError: column "name" of relation "django_content_type" does not exist

 

아래의 sql을 해당 디비에서 실행시켜 칼럼을 추가 해 줍니다. 

ALTER TABLE django_content_type ADD COLUMN name character varying(50) NOT NULL DEFAULT 'someName';

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret

EFK의 설치는 아래의 포스팅을 참조했습니다. 

https://lng1982.tistory.com/281

 

EFK Stack 구축 using Docker compose

Elasticsearch + Fluentd + Kibana 조합을 EFK Stack이라 부른다. 참고로 Elasticsearch + logstash + Kibana 조합은 ELK Stack 이다. Fluentd : 오픈소스 log collector Elasticsearch : Lucene 기반 분산 검색..

lng1982.tistory.com

위의 포스팅을 잘 따라 했다면 kibana에서 로그를 볼수 있는 화면이 나온다. 

그러면 실제 django의 logger를 전송해보자.

 

1. django-fluentd 패키지 설치 

$ pip install django-fluentd

or

git clone https://github.com/jayfk/django-fluentd.git
cd django-fluentd
python setup.py install

2. settings에 logger 설정 추가 

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'fluent_formatter': {
            '()': 'fluent.handler.FluentRecordFormatter',
            'format': {
                'level': '%(levelname)s',
                'module': '%(name)s',
                'message': '%(message)s',
                'time': '%(asctime)s',
                'file': '%(filename)s',
                'line': '%(lineno)d',
            },
            'datefmt': '%Y-%m-%d %H:%M:%S',
        }
    },
    'handlers': {
        'fluent': {
            'level': 'INFO',
            'class': 'fluent_support.DjangoFluentHandler',
            'tag': 'app.log',
            'host': 'localhost',
            'port': 24224,
            'formatter': 'fluent_formatter'
        },
    },
    'loggers': {
        'django': {
            'handlers': ['fluent'],
            'propagate': False,
            'level': 'INFO',
        },
    }
}

formatters은 로그의 포멧을 지정합니다. 

handlers은 사용할 로그 패키지와, 어떠한 포멧으로 할지 지정합니다. 

loggers은 지정한 app / 프로젝트를 지정하며('', django로 설정하면 프로젝트 전체가 됩니다. ),

           사용할 handler, 로그의 레벨을 지정합니다. 

즉  loggers에서 INFO로그로 핸들러를 'fluent'로 지정했으며, 핸들러에서는  fluent에서 포멧을 'fluent_formatter'로 지정했으며, fluent_support로 설정했습니다. 

 

 

3. fluent_support.py 파일 추가 (프로젝트 최상위에 추가 해주세요.)

# coding: utf-8
import json
import logging
import socket

from fluent import sender


class DjangoFluentHandler(logging.Handler):
    def __init__(
            self, tag, host='localhost', port=24224, timeout=3.0,
            verbose=True):
        logging.Handler.__init__(self)
        self.tag = tag
        self.sender = sender.FluentSender(tag,
                                          host=host, port=port,
                                          timeout=timeout, verbose=verbose)
        self.hostname = socket.gethostname()

    def emit(self, record):
        if record.levelno < self.level:
            return
        msg = self.format(record)
        data = {
            'host': self.hostname,
            'name': record.name,
            'levelname': record.levelname,
            'process': record.process,
            'message': json.dumps(msg),
        }
        self.sender.emit(None, data)

    def _close(self):
        self.sender._close()

django logger는 emit의 함수가 호출되는데 결국 data를 fluentd로 전송하게 됩니다. 이제 data에 필요한 부분만 넣어주시면 마음껏 커스텀이 됩니다. 

 

서버를 실행하고, 페이지를 출력 해보면 kibana에서 로그를 확인을 할 수 있습니다!!

 

 

 

참조

https://tokibito.hatenablog.com/entry/20131203/1386006672

 

Djangoのログ出力をFluentdで集める - 偏った言語信者の垂れ流し

Djangoのログ出力をFluentdで集める方法について。 ログレベルがERRORやWARNINGのものはSentryを使うのが便利だと思うけど、それ以外のINFOやDEBUGはSentryに入れるには数が多すぎるのでどうするか考えてて、最初はローカルのファイルに書き出していた。 けどまあ複数のサーバーにログファイルがあるとやっぱり不便だったので、Fluentdを使って一箇所に集めることにした。 簡単にできるかなーと思ってたんだけど、fluent-logger-pythonのlogging用のハンドラのイ

tokibito.hatenablog.com


WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret

다른 프레임워크를 하다가 다시  django를 하다가 당혹스러운 경험입니다. 

 

django의 models.OneToOneField는 데이터가 default시 (데이터 변경이 없다면) 해당 row가 생성되지 않습니다. 

 

해당 이미지는 예제 입니다. (django의 user는 위와 같지 않습니다.)

위와 같은 관계를 가질때  보통 user를 생성하면 user_profile도 디폴트로 생성됩니다. (보통의 orm에선 말이죠..)

하지만 django에서는 디폴트로 생성되지 않습니다!!!!!! 생성시 profile의 데이터를 변경하면 그때 생성됩니다. 

만일 디폴트로 생성후 profile이 없는 상태에서 profile에 참조하게 된다면?? 에러가 터지죠. (저와 같이 말이죠.. 머리도 터집니다.)

 

넵 방법은 있습니다. 

 

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

 

위의 방법처럼  @receiver로 user가 생성할 때 마다 하는 참조하는 방법은 절대 쓰지 마세요!!!!

나중에 더 터집니다.

 

 

django-annoying 패지키의 AutoOneToOneField으로 필드 속성을 바꿔주세요.

from annoying.fields import AutoOneToOneField

class MyProfile(models.Model):
    user = AutoOneToOneField(User, primary_key=True)
    home_page = models.URLField(max_length=255)
    icq = models.CharField(max_length=255)

https://stackoverflow.com/questions/1652550/can-django-automatically-create-a-related-one-to-one-model

 

Can Django automatically create a related one-to-one model?

I have two models in different apps: modelA and modelB. They have a one-to-one relationship. Is there a way django can automatically create and save ModelB when modelA is saved? class ModelA(mod...

stackoverflow.com

 

기존 필드라면 마이그레이션도 해주셔야합니다.

 

그러면 마찬가지로 default상태일때는 똑같이 생성이 되지 않지만, 참조시 자동으로 생성됩니다.!!( 그래서 에러가 나지 않습니다.)

 

혹시나 필수값을 받지 않는 상태의 row이며,  oneTooneField일 경우엔 annoying를 쓰세요.

 

그래야 미래의 내가 편해집니다.


WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret

장담한다. 

기본 기능 이외의 기능을 찾는다면 웬만하면 쓰지 말자.

그냥 그 시간에 만드는게 더 빠르다. 

정말이다.

swagger에서 지원하는 기능을 이제야 만들고 있으므로 큰 기대 말고, 

기본 기능외는 찾지 말고 그냥 하나 만들어서 쓰는 게 당신에게 이익이다.

'web > Django_rest_framework' 카테고리의 다른 글

django에서 swagger로 한다면 drf_yasg 는 왠만하면....  (0) 2019.05.20
django REST_FRAMEWORK login  (0) 2019.01.11
9. href  (0) 2016.07.30
8 pagination  (0) 2016.07.29
7 search  (0) 2016.07.28
6 저장/수정시 유저 저장  (0) 2016.07.27

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret


REST_FRAMEWORK에서 오른쪽 상단의 로그인을 통해 로그인을 해도 세션이 유지가 안되고, 

유저 객체가 AnonymousUser만 뜬다면


setting 의 REST_FRAMEWORK 속성에 auth관련 속성을 추가해 주면 된다.

REST_FRAMEWORK = {

    .......

    'DEFAULT_AUTHENTICATION_CLASSES': (

        'rest_framework.authentication.TokenAuthentication',

        'rest_framework.authentication.SessionAuthentication'

    )

}


'web > Django_rest_framework' 카테고리의 다른 글

django에서 swagger로 한다면 drf_yasg 는 왠만하면....  (0) 2019.05.20
django REST_FRAMEWORK login  (0) 2019.01.11
9. href  (0) 2016.07.30
8 pagination  (0) 2016.07.29
7 search  (0) 2016.07.28
6 저장/수정시 유저 저장  (0) 2016.07.27

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret

nginx + uwsgi 연동

web/Django 2019.01.11 03:29


uwsgi 연동 에서 이어짐


nginx 설치 

$ sudo apt-get install nginx


nginx에 프로젝트 설정 파일 추가 

$ cd /etc/nginx/sites-available/

$ sudo vi django_project.conf

server {

    listen 80; # 수신 포트 설정

    server_name _; # 도메인 설정 ip로 할경우 언더바 _ 로 하면 됨 

    location / { 

        # 요청을 전달할 소켓 파일 지정 (해당 파일은 uwsgi.ini에서 socket로 지정했음)

        uwsgi_pass unix:///tmp/django_project.sock; 

        include uwsgi_params; # uwsgi 사용, 리눅스에서 소켓은 파일처럼 취급된다.

    }

}


/etc/nginx/sites-enabled/ 에도 같은 파일이 필요. 심볼릭 링크로 추가

$ ln -s /etc/nginx/sites-available/django_project.conf /etc/nginx/sites-enabled/


!! 아이피로 할경우 default의 파일과 충돌하여 작동하지 않습니다. 도메인이 아닌 ip로 할경우 default파일을 지워줘야 합니다. ( 도메인이면 지우지 않아도 됩니다.)

$ sudo rm /etc/nginx/sites-enabled/default

$ sudo rm /etc/nginx/sites-available/default



nginx 재시작

$ sudo service nginx start

'web > Django' 카테고리의 다른 글

EFK docker + django logger 커스텀  (0) 2019.07.21
django models.OneToOneField는 변경할때 생성이 됩니다.  (0) 2019.07.03
nginx + uwsgi 연동  (0) 2019.01.11
uwsgi -- unavailable modifier requested: 0 --  (0) 2019.01.10
ubuntu uwsgi  (0) 2019.01.10
django middleware  (0) 2016.08.15

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret


nginx + uwsgi 로 진행시 


-- unavailable modifier requested: 0 --

-- unavailable modifier requested: 0 --

-- unavailable modifier requested: 0 --



와 같이 접근이 안된다면 python3의 패키지나 옵션을 추가해 주시면 됩니다. 


1. uwsgi-plugin-python3 를 설치하고 다시 시작

$ sudo apt-get install uwsgi-plugin-python3


2. uwsgi 실행시  --plugin python3 옵션을 추가해서 시작

$ sudo uwsgi -i uwsgi.ini --plugin python3

'web > Django' 카테고리의 다른 글

django models.OneToOneField는 변경할때 생성이 됩니다.  (0) 2019.07.03
nginx + uwsgi 연동  (0) 2019.01.11
uwsgi -- unavailable modifier requested: 0 --  (0) 2019.01.10
ubuntu uwsgi  (0) 2019.01.10
django middleware  (0) 2016.08.15
django-summernote 사용하기  (4) 2016.07.23

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret

ubuntu uwsgi

web/Django 2019.01.10 00:49

가상환경 추가

$ virtualenv -p python3 venv


django 설치 및  프로젝트 생성

$ sudo apt-get install build-essential python-dev

$ pip3 install uwsgi

$ pip3 install django 

$ cd ~

$ django-admin.py startproject django_project


uwsgi 실행 확인 (에러시 포트 바인딩 확인)

$ cd django_project

$ uwsgi --http :8089 --module django_project.wsgi


ini 파일로 uwsgi 실행 

$ cd ..

$ vi uwsgi.ini

( base 의 경로 확인 필요 )

[uwsgi]


base = /home/ubuntu

project = django_project

chdir = %(base)/%(project) 

module = %(project).wsgi:application   

master = true    

processes = 1    

socket= /tmp/%(project).sock  

chmod-socket = 666

vacuum = true    

pidfile = %(base)/%(project).pid 

daemonize = %(base)/%(project).log


$ uwsgi -i uwsgi.ini



데몬으로 uwsgi 실행 ( uwsgi 설치 )

$ sudo apt-get install uwsgi

$ sudo apt-get install uwsgi-plugin-python3


$ sudo uwsgi -i uwsgi.ini

-> [uWSGI] getting INI configuration from uwsgi.ini 

출력과 함께 실행됨

로그를 보고 싶다면

$ tail -f -n 1000 django_project.log (ini파일의 deamonize의 경로의 log 파일)


uwsgi 종료시

$  sudo uwsgi --stop django_project.pid (ini 파일의 pidfile 경로의 pid 파일)




'web > Django' 카테고리의 다른 글

nginx + uwsgi 연동  (0) 2019.01.11
uwsgi -- unavailable modifier requested: 0 --  (0) 2019.01.10
ubuntu uwsgi  (0) 2019.01.10
django middleware  (0) 2016.08.15
django-summernote 사용하기  (4) 2016.07.23
get 방식의 글자 256자 제한은 잘못된 상식  (2) 2016.05.24

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret


1. script 는 기본적으로 window 객체 안에서 돌아간다.

2. 로드된 스크립트들은 window객체 안에 있고, 모듈간의 의존성 문제, 변수 및 함수의 침범이 일어났다.

3. 이를 방지하기 위해 commonJS / AMD(Asynchronous Module Definition) 가 생겨났고, es6 또한 제공하기 시작

AMD              require([""], function(module) {})

CommonJS    var module = require("")

ES6                 import { module } from "";

4. 서로 지원하는게 달라서 춘추전국시대가 열림

5. 이 모든것을 통합 해주는 babel 등장 ( js 하위버전으로 변환까지 해줌 ) 으로 결국 모두 바벨 사용해야함.



- 읽어보기

https://blog.pigno.se/post/157992405313/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-%EC%A0%9C%EA%B3%B5%EC%9D%84-%EC%9C%84%ED%95%9C-amd-commonjs-%EA%B7%B8%EB%A6%AC%EA%B3%A0-requirejs-%EC%86%8C%EA%B0%9C

https://d2.naver.com/helloworld/591319


# 결국 node는 commonjs / 웹팩은 AMD / 클라이언트 프레임워크 ES6를 선택...... 이게 무슨..

'web > javascript' 카테고리의 다른 글

javascript 의 모듈 제공 방법  (0) 2018.09.05
js regexp wrong results?  (0) 2018.05.03
overflow-x 된 DOM에서 마우스 휠로 좌우스크롤 움직이기  (0) 2016.06.29
javascript reduce  (0) 2016.06.10
javascrpt map  (0) 2016.06.09

WRITTEN BY
No.190
세계정복의 시작점

트랙백  0 , 댓글  0개가 달렸습니다.
secret