[javascript] 함수 할당시 실행 없이 인자 넘기기

Problem

var apiCRUD  = {
  downloadExcel: function($http) {
    //랄랄랄
  }
}

rc.downloadExcel = apiCRUD.downloadExcel($http);

apiCRUD.downloadExcel함수를 저렇게 rc.downloadExcel에 할당하면 바로 실행이 되는데,
나는 rc.downloadExcel이 호출되었을 때 apiCRUD의 함수가 실행되길 바란다.

그렇다고

rc.downloadExcel = apiCRUD.downloadExcel;

처럼 하면 $http인자를 못 넘긴다.

Solution

rc.downloadExcel = function() {
    apiCRUD.downloadExcel($http);
}

요러면 됨.
호이스팅 없이 함수 실행 시에 불리움.

Refer

j2p님의 도움 감사합니다.

구글 애널리틱스 용어 정리

세션 [Session]

웹사이트 방문수를 가공한 새로운 단위.
세션의 첫 번째 조회와 함께 누적됨.
오늘 밤부터 쓰는 google analytics page 30 참고.

사용자 수 [Users]

순 방문자 수

방문수(접속수) [Entrances]

세션의 첫 번째 페이지뷰 / 화면조회와 함께 누적됨.
맨 처음 방문했을 때 카운팅.

페이지뷰 수 [Pageviews]

페이지뷰가 일어날때마다 매번 카운팅.
한 사용자가 새로고침 눌러도 또 카운팅.

순 페이지뷰 수 [Unique pageview]

같은 사람&세션이라면 하나로 카운팅.
한 방문 내에서 발생하는 페이지뷰의 수.

세션당 페이지수

한 번 방문시 평균적으로 몇 개의 페이지를 보았느냐?
중요하게 보아야 할 지표.

이탈률(반송률) [Bounce rate]

방문자가 하나의 페이지만 보고 바로 나가는 경우 그 페이지로 시작하는 방문을 바탕으로 계산.
방문객이 처음으로 본 페이지를 대상으로 한다.
중요하게 보아야 할 지표.
웹사이트에 대한 사용자의 평가를 반영하는 지표.

이탈률이 70% = 100명 중 70명은 한 페이지만 보고 바로 나가고 30명은 다른 페이지를 본다.

수학방 이탈률/종료율
이탈률 계산은 이 링크를 유심히 보세요. 헷갈리기 쉽습니다.

이탈률(%)(종료율) [Exit rate]

웹사이트 이곳저곳 방문하다가 해당 페이지에서 나가버린 비율.
높다고 무조건 나쁜것이 아닌다. 목적을 달성했기 때문에 Exit할 수 있으니.

이벤트 [Event]

웹페이지/화면 로드와는 별개로 추적할 수 있는 콘텐츠와 사용자 간의 상호작용.
개발자가 따로 코드를 삽입하거나 태그매니저를 사용하여 달 수 있다.
(e.g. 이벤트 참여, 동영상 재생, 특정 요소 클릭)

전환 [Conversion]

비지니스의 성공에 중요한 요소. 사이트 내에서 완료된 활동.
e.g. 이메일 뉴스레터 가입완료(목표 전환), 구매(전자상거래 전환)

세그먼트 [Segment]

필터같은 것.

Refer

http://www.bbscanvas.co.kr/ga/googleanalytics1/
http://analyticsmarketing.co.kr/digital-analytics/google-analytics-4-%EA%B5%AC%EA%B8%80-%EC%95%A0%EB%84%90%EB%A6%AC%ED%8B%B1%EC%8A%A4%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EB%A9%94%EB%89%B4-%EC%A3%BC%EC%9A%94-%EC%9A%A9%EC%96%B4%EC%99%80-%EA%B0%9C%EB%85%90/

[Django] redirect시에 데이터 넘기고 싶어요(feat. HTTP)

상황

페이스북 로그인을 하고, 페이스북 연결 해제버튼을 눌렀을 때 비밀번호가 설정이 되어있지 않다면 비밀번호 설정 페이지로 리다이렉트 시키고 싶다.
이로 인해서 들어온 비밀번호 설정 페이지에서는 그냥 들어왔을 때와는 다르게 “페이스북 연결을 해제하려면 비밀번호를 설정해주셔야 합니다”라는 안내멘트를 보여주고 싶은데, 이를 위해 리다이렉트 시켰을 때 데이터를 넘기고 싶다.

첫 시도

Django docs에서 redirect섹션을 보고,

def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

이렇게 뒤에 foo=’bar’로 넘기면 되겠다 생각했다. (허접이 스키밍을 했을때의 폐해) (여기서 뒤에 붙는 인자는 kwargs이다.)
하지만 인자는 넘어가지 않았고, ‘django pass data with redirect’ 키워드로 구글링을 해보았다.
스택오버플로우링크의 답변을 보았는데,

redirect is merely a wrapper around HttpResponseRedirect that automatically calls reverse for you to create the URL to redirect to. As a result, the parameters you pass to it, aren’t arbitrary, they must be same you would pass to reverse and, specifically, only those required to create the URL.

Many people seem to have troubles understanding that data can’t just be arbitrarily passed to a view. HTTP is a stateless protocol: each request exists on it’s own, as if user had never been to any other page of the site. The concept of a session was created to provide a sense of “state” to a cohesive unit such as a site. With sessions, data is stored in some form of persistent storage and a “key” to look up that data is given to the client (typically the user’s browser). On the next page load, the client sends the key back to the server, and the server uses it to look up the data to give the appearance of state.

As a result, if you need data from one view available in another, you need to add it to the session, do your redirect, and look up the data in the session from the next view.

내가 찾던 답변같은데 이해하기 쉽지 않았다.
대략 HTTP의 stateless한 특성으로 reverse로는 데이터를 넘길 수 없어, 다른 방안을 찾으라는 것 같아 또 이것 저것 읽어본 결과,
1. Session을 사용하여 넘기기
2. GET으로 뒤에 Parameter달아 넘기기
3. django messages 사용하기

정도의 방법이 있는데, 지금 상황에서 어떤 방법을 써야 좀 더 세련될지 조언을 구하고자 P모님께 질문을 하였다. 결론은 역시 나의 HTTP에 대한 이해부족에서 나온 삽질이었다는 것이다.

HTTP의 Stateless성

P모님: HTTP는 왜 상태가 없죠?
나: (???)

한 초밥집이 있다. 이 초밥집은
1. 손님이 30분간 밥을 먹을동안 주방장이 계속 붙어서 손님에게 초밥을 내어줌
2. 테이크아웃
두가지 방식으로 운영될 수 있다.
1은 서로가 서로의 상태를 바로바로 알 수 있지만 한 손님이 먹는동안 주방장이 다른 손님을 응대하지 못한다는 단점이 있다.
2는 서로의 상태를 유지하고 있지 않지만, 한 주방장이 여러 손님을 순차적으로 응대할 수 있다는 장점이 있다.

보통 채팅이나 게임같은 실시간성 서비스가 1의 형태, 웹은 2의 형태를 취한다.

만약 2 방식에서 주방장이 손님의 단골메뉴를 기억해야 한다 해보자.
주방장이 손님별로 단골메뉴를 적어두거나, 손님이 각자 단골메뉴 쿠폰을 들고있다가 주방장에게 주어 기억하는 방법이 있을것이다. session을 사용하는것이 여기에 속한다. 이 방식의 특징은 서버의 디비와 사용자의 브라우저에 데이터를 저장한다는 것이다. 굳이 세션에 저장할 필요 없는 데이터를 저장하면 불필요하게 디비를 한 번 더 다녀오는 비용이 들게 된다. 그리고 django의 messages도 세션을 사용해서 구현한 것이니 위의 3가지 방법 중 1은 3을 포함하게 된다.
그리고 2번, GET으로 뒤에 파라미터를 달아 넘기는 것은, 아예 처음부터 다른 주소로 들어가는 것이다. 지금 상황처럼 이 url자체로 사람들이 많이 들어올 걱정을 안 해도 된다면 충분히 GET으로 데이터를 넘겨도 되겠다.

참고 – 쿠키와 세션 개념

render, redirect, reverse의 차이

그렇다면 왜 redirect에서 데이터를 인자로 넘기는게 안되는 것일까? 이는 HTTP의 response때문이다.
HTTP의 requestPOST혹은 GET등으로 데이터를 뭍혀서 보낸다.
그리고 온 response엔 200, 404 등 많은 종류가 있다. 여기서 200 ok같은 경우는 헤더영역에 200 등이 써있고, 그 밑에 html문서가 오던지, 혹은 요청한 데이터들이 좌라락 오던지 한다. 하지만 300번대인 redirect는, 밑에 redirect될 주소만 띡 하고 온다. 데이터를 뭍힐 곳이 없는것이다. (참고: HTTP 상태 코드)
(참고: 301은 permanent한 이동, 302는 임시 이동)

그리고 redirect, reverse의 관계는 아래와 같다.

  • redirect(‘welcome’) : 원래 redirect('/some/url/')처럼 url을 주소로 써주는데, url name을 쓰면 redirect 내부에서 자동으로 reverse를 호출하여 이름을 매칭해서 보내준다.
  • reverse(‘welcome’): url name welcome을 찾아서 보내준다.
  • redirect(reverse(‘welcome’)): 즉 이렇게 안쓰고 그냥 redirect만 써도 된다.

render는 템플릿과 컨텍스트를 합쳐서 HttpResponse 오브젝트를 리턴한다. 여기서 합친다는 말은, 예를 들어 컨텍스트에서 {"foo": "bar"}를 넘겼다고 하면, html template에서 {{ foo }}를 찾아서 bar로 치환해 섞어서 HttpResponse로 리턴해준다는 말이다.

그래서 HttpResponseRedirect를 리턴하는 redirect()는 합칠 컨텍스트를 못 받는 것이다.
참고: [Django] HttpResponse VS HttpResponseRedirect

결론

HTTP 부들부들

[Django] HttpResponse VS HttpResponseRedirect

의문

redirect
reverse
redirect(reverse(‘password-set’))
return HttpResponseRedirect(reverse(‘news-year-archive’, args=(year,)))
render
render_to_response
차이가 뭐지

redirect(‘welcome’)
reverse(‘welcome’)
redirect(reverse(‘welcome’)) 차이?

HttpResponseRedirect랑 HttpResponse 차이는 뭐지

Django shortcut functions

render()

render(request, template_name, context=None, context_instance=_context_instance_undefined, content_type=None, status=None, current_app=_current_app_undefined, dirs=_dirs_undefined, using=None)

템플릿과 컨텍스트를 합쳐서 HttpResponse 오브젝트를 리턴함.

from django.shortcuts import render

def my_view1(request):
    # View code here...
    return render(request, 'myapp/index.html', {"foo": "bar"},
        content_type="application/xhtml+xml")


def my_view2(request):
    # View code here...
    t = loader.get_template('myapp/index.html')
    c = {'foo': 'bar'}
    return HttpResponse(t.render(c, request),
        content_type="application/xhtml+xml")

(my_view1과 my_view2는 동일한 코드)

render_to_response()

render_to_response(template_name, context=None, context_instance=_context_instance_undefined, content_type=None, status=None, dirs=_dirs_undefined, using=None)

별로 권장하지 않음. render()이랑 비슷한데 response에서 request가 불가능한 차이가 있다.

return render_to_response('my_template.html',
                          my_context,
                          context_instance=RequestContext(request))

redirect()

redirect(to, permanent=False, *args, **kwargs)

패스된 인자를 가지고 HttpResponseRedirect를 리턴한다

def my_view(request):
    ...
    # return redirect('/some/url/') # 요렇게 하드코드 URL로 써도 됨.
    return redirect('some-view-name', foo='bar')

get_object_or_404()

get_object_or_404(klass, *args, **kwargs)

준 모델을 get()해오지만, 모델이 DoesNotExist익셉션 되면 Http404를 raise한다.

from django.shortcuts import get_object_or_404

def my_view(request):
    my_object = get_object_or_404(MyModel, pk=1)

django.core.urlresolvers utility functions

reverse()

reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

urls.py에서 만든 url name 사용할 수 있음

reverse('news-archive')

def myview(request):
    # url이 argument를 받는 경우
    return HttpResponseRedirect(reverse('arch-summary', args=[1945])) 


# kwargs를 쓰는 방법. '/admin/auth/'로 간다.
reverse('admin:app_list', kwargs={'app_label': 'auth'})

HttpRespose VS HttpResponseRedirect

링크

HttpResponse

response = HttpResponse("Here's the text of the Web page.")
– HTTP코드가 200(ok)이고 생성자로 전달된 컨텐츠를 포함한 HttpResponse오브젝트를 만든다.
– 보통 작은 response에서만 쓴다. (ajax로 받은 데이터나, 작은 number 등)

HttpResponseRedirect

HttpResponseRedirect("http://example.com/")
– HTTP코드가 302(Found/Moved temporarily)인 HttpResponse오브젝트를 만든다.
– 다른 페이지로 redirect할때만 써야한다(e.g. 폼 POST전송 성공 이후)

결론

여전히 헷갈린다.

refer

http://makerj.tistory.com/220

[개발] Underscore VS Dash, 무엇을 써야 하는가

개인별로 선호하는 스타일이 있겠지만, 서로 알아듣기 편하면 더 좋겠죠?

Dash (-)

  • End user에게 더 익숙하다.
  • 그러므로 url같이 노출되는 영역엔 언더스코어보단 dash(/abount-us) 구글 권고
  • CSS class에서도 dash로 많이 쓴다.

Underscore (_)

  • 보통 띄어쓰기의 의미로 쓴다(+도 많이들 그런다. plus+means+space)
  • 파이썬 등 프로그래밍 소스에서 파일명에서 쓴다 (e.g. password_reset_form.html)
    • 프로그래밍 언어에서 dash가 ‘minus’의 의미일 때가 많음

저 둘 덕분에 꾸벅 인사를 할 수 있습니다. (- -)(_ _)

refer

http://stackoverflow.com/questions/119312/urls-dash-vs-underscore
https://support.google.com/webmasters/answer/76329?hl=ko