request の GET.get, GET.getlist, body とかを python で生成する

業務をしていて、いままで当たらなかったケースに遭遇したのでメモ。

ケース

普段 urls.py から呼ばれる hogehoge と fugafuga がある。

def hogehoge(request):
    ...(略)...

def fugafuga(request):
    ...(略)...

hogehoge から fuagfuga を呼び出したい。

def hogehoge(request):
    fugafuga(request):

def fugafuga(request):
    ...(略)...

request の method, body, get, getlist を解決出来ないので。

def hogehoge(request):
    fugafuga(request):

def fugafuga(request):
    # method
    print(request.method)
    # body
    print(request.body)
    # get
    print(request.GET.get('spam'))
    # getlist
    print(request.GET.getlist('egg'))

解決 1

GET は QueryDict を、body は _body を指定して request のパラメータを解決する。

def hogehoge(request):
    r = request
    r.method = 'POST'
    r.GET = QueryDict('spam=1&egg=2&egg=3', mutable=True)
    r._body = json.dumps({'body_key': 'body_value'})
    fugafuga(r)

def fugafuga(request):
    # method
    print(request.method)  # POST
    # body
    print(request.body)  # {"body_key": "body_value"}
    # get
    print(request.GET.get('spam'))  # 1
    # getlist
    print(request.GET.getlist('egg'))  # ['2', '3']

解決 2

request に手を加えたくない場合は、インスタンスを使う方法も。

class R():
    def method(self):
        return
    def GET(self):
        return
    def body(self):
        return
    def POST(self):
        return

def get_marker_datas(request):
    r = R()
    r.method = 'POST'
    r.GET = QueryDict('spam=1&egg=2&egg=3', mutable=True)
    r.body = json.dumps({'body_key': 'body_value'})  # _body → body に。
    fugafuga(r)

def fugafuga(request):
    # method
    print(request.method)
    # body
    print(request.body)
    # get
    print(request.GET.get('spam'))
    # getlist
    print(request.GET.getlist('egg'))

実際は

上記の例だと print を fugafuga から hogehoge に移植すれば良いですが、実際は下記のような状態で fugafuga とその配下の関数に手を加えるとなると影響範囲が大きいので request のパラメータを設定して対応しました。

def fugafuga(request):
    ham(request)
    egg(request)
    spam(request)

def ham(request)
    ham_hoge(request)
    ham_fuga(request)
    ham_bar(request)