Your wish is my command

It’s a long journey

Django 문서에 나오지 않은 Filter Lookup

http://docs.djangoproject.com/en/1.3/topics/db/queries/#field-lookups 에 필터에 사용할 수 있는 것들이 있는데, 여기에 나와있지 않는 것들이 있다. django가 문서가 충실한 편이라 여기만 열라 뒤졌으나 원하는 것 찾지못하고.. 설마 없겠어? 하고 소스코드를 뒤져보니 보인다… ^^;

django/models/sql/constants.py

  • in
  • range
  • year, month, week_day,
  • search
  • regex

추가: 근데 허탈하게도 문서에 있더라는… http://docs.djangoproject.com/en/1.3/ref/models/querysets/#field-lookups

내가 찾던게 뭐냐고? in과 range다~ ㅋㅋ

Mako Expression Filtering, Decorator

http://www.makotemplates.org/docs/filtering.html#expression-filtering

  • u : URL escaping, provided by urllib.quote_plus(string.encode(‘utf-8’))
  • h : HTML escaping, provided by markupsafe.escape(string) (new as of 0.3.4 - prior versions use cgi.escape(string, True))
  • x : XML escaping
  • trim : whitespace trimming, provided by string.strip()
  • entity : produces HTML entity references for applicable strings, derived from htmlentitydefs
  • unicode (str on Python 3): produces a Python unicode string (this function is applied by default).
  • decode. : decode input into a Python unicode with the specified encoding
  • n : disable all default filtering; only filters specified in the local expression tag will be applied.

필터는 그냥 스트링 인자를 하나 받는 함수이므로 작성하기도 편하다.

그런데 아쉽게도 필더에 파라미터가 들어가지 않는구나..

http://www.makotemplates.org/docs/filtering.html#decorating

mako의 함수에 python의 decorator처럼 사용할 수 있다. 멋진데?

Django: request.user에 나만의 User를 넣기?

음.. 제목이 이상하긴 한데… django의 authentication을 사용하면 request.user에 django.contrib.auth.models.User 객체가 생긴다. 그런데 말이다 처음부터 django를 사용할 경우는 이거 쓰면 되는데, 이미 돌아가는 프로젝트를 django로 옮겨가는 경우 django의 user가 맞지 않는게 있다.

first_name, last_name 등은 어쩌면 우리나라의 환경에 맞지 않는 것일 수 도 있고, username 보다는 userid가 더 알아먹기 편하니 말이다.. 물론 이미 기존 데이터베이스도 그렇게 되어있을 것이고…

이런 상황에서 request를 처리할때 django의 스타일과 다르게 user를 가져오는 것도.. 솔직히 맘에 들지 않는다. 남이 고민고민해서 만들어 놓은 것은 되도록이면 그들의 철학에 맞게 쓰자는게 나의 주의니깐…

그래서 고심끝에 request.user를 사용하되 request.user가 django가 지원하는 것이 아닌 나만의 custom user 모델로 생성하고, 그리고 몇몇 django에서 필요한 메소드의 함수만 만들어 주면 될 것이라 생각하고 작업했더니 아주 나이스하게 돌아긴다..~~

django.user를 설정하는 곳은 middleware이니 나도 새로운 middleware를 만들어서 처리했다. 물론 django authentication의 코드를 좀 참고했다. 대충 아래 코드 보시고…

from myapp.models import AnonymousUser, User

class LazyUser(object):
    def __get__(self, request, obj_type = None):
        if not hasattr(request, '__user'):
            request.__user = User.objects.get(id=request.session['user_id']) if request.session.get('user_id', False) else AnonymousUser()
        return request.__user

class AuthenticationMiddleware:
    def process_request(self, request):
        if not hasattr(request.__class__, 'user') or not request.__class__.user is LazyUser:
            request.__class__.user = LazyUser()

이렇게하면 이제 request.user를 우리만의 user객체로 사용가능하니.. 좋다~

실제 작성했던 코드에서 대충 개념만 표현한 것이라 제대로 동작할 지는 나도 모른다.. ㅋㅋ

파라미터가 있는 Decorator

Python의 Decorator 기능은 한마디로 멋지다. 잘 쓰면 유용하지… 근데 작성하면 항상 헷갈린단 말이지…

decorator에 파라미터를 넘겨주고자 하는 경우에도 상당히 헷갈린다. 파라미터가 없는 것하고 형태가 아주 또 달라지거든.. 간단히 기억하자 파라미터가 있는 데코레이터는 wrapp 함수를 한번 더 두어야한다는 것..

def prefix_decorator(func):
        def new_func(*args, **kwargs):
                return 'prefix: ' + func(*args, **kwargs)
        return new_func

def my_decorator(str):
        def wrap(func):
                def new_func(*args, **kwargs):
                        return func(*args, **kwargs) + ' :' + str
                return new_func

        return wrap

@prefix_decorator
@my_decorator('added by decorator')
def test():
        return "I'm test"

print test()

실행 결과는 아래와 같음..

prefix: I'm test :added by decorator

Python-mcrypt 사용 예

python-mcrypt은 문서가 없다. 포함된 test.py를 보면 되는데… 좀 길고..

#! -*- encoding: utf8 -*-
import base64
import urllib
import mcrypt
import random
import string

def random_string(length):
        return ''.join([random.choice(string.ascii_letters + string.digits) for x in range(length)])

chiper_key = random_string(16)

# encode
def encrypt(data):
        m = mcrypt.MCRYPT('rijndael-256', 'cfb')
        iv_size = m.get_iv_size()
        iv = random_string(iv_size)

        m.init(chiper_key, iv)
        return base64.b64encode(m.encrypt(iv + data))


# decode
def decrypt(data):
        data = base64.b64decode(data)
        m = mcrypt.MCRYPT('rijndael-256', 'cfb')
        iv_size = m.get_iv_size()
        iv = data[:iv_size]
        encrypted = data[iv_size:]
        m.init(chiper_key, iv)
        return m.decrypt(encrypted)

data = '안녕하세요'
assert data == decrypt(encrypt(data))

MySQL XXX_general_ci면…

MySQL에서 LIKE로 검색하는데 이놈이 대소문자를 구별하지 않고 검색하는거다. 이거 참 이놈은 ILIKE가 기본값인가? 하고 넘어갔었는데 오늘은 = 로 검색하는데도 대소문자를 구별하지 않고 검색하는거다… 나로썬 황당~

주위 분들게 물어봤더니 euckr_general_ci로 되어있으면 기본으로 대소문자를 구별하지 않는다고 한다. _cs면 대소문자를 구분한다나… ㅡㅡ

뭐 이런 일이… 하여간 이상한 MySQL이다.~

그럼 Case Sentive 검색을 하려면 어떻게 하느냐? euckr_general_ci는 Case Insentive로 되기때문에 _cs로 해야하는데 euckr_general_cs가 없다. 대신 euckr_bin이 있으니 그걸로 하면 된다.

select field from table where field COLLATE euckr_bin = 'test string'

Ubuntu 휴지통 아이콘 보이기

이상하게 우분투 시스템에 휴지통 아이콘이 없어서 찾아봤더니 아래처럼 하면 휴지통이 보인다..

http://www.howtogeek.com/howto/ubuntu/add-the-trash-can-icon-to-your-ubuntu-desktop/

http://zodiac12k.egloos.com/1382797

그리고 휴지통을 열었더니, 지금까지 삭제한 파일이 거의 5G가 있네… 숨어있는 5G를 찾았다.!

근데 왜? 삭제하면 휴지통으로 보내면서 휴지통이 기본으로 안보이게 한거야!!