2012-11-23 9 views
11

Tôi đang sử dụng Flask và MongoDB. Tôi đang cố gắng chuyển đổi nội dung của request.form thành một cái gì đó phù hợp để tiết kiệm thông qua PyMongo. Nó có vẻ như một cái gì đó mà nên đến thường xuyên, đủ để có một giải pháp làm sẵn.Trong Flask chuyển đổi hình thức đối tượng POST thành một đại diện phù hợp cho mongodb

Vậy điều gì Flask cho tôi là cái gì đó như:

ImmutableMultiDict([('default', u''), ('required': u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')]) 

Và những gì tôi đang tìm kiếm để có được một cái gì đó như thế này:

{ 
    'default': '', 
    'name': ['short_text', 'another'], 
    'required': true 
} 
+0

Tại sao bạn cần điều đó? bạn có thể truy cập các giá trị khi bạn truy cập trong từ điển mà không cần chuyển đổi. như d ['required'] cho bạn trả lại đúng. –

+0

@Abdul, nếu bạn muốn lặp qua ImmutableNutiDict(), thì bạn có thể làm như từ điển thông thường, nhưng nếu bạn muốn sử dụng nó như một tổng thể như một dict, ví dụ, nhập từ điển bằng cách sử dụng z = {** x, ** y}, sau đó nó không hoạt động, giá trị sẽ có hình vuông xung quanh nó, như {..., 'name': ['short_text'],}. – zhihong

Trả lời

15
>>> from werkzeug.datastructures import ImmutableMultiDict 
>>> imd = ImmutableMultiDict([('default', u''), ('required', u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')]) 
>>> imd.to_dict(flat=False) 
>>> {'default': [''], 
'name': ['short_text', 'another'], 
'required': ['on'], 
'submit': ['Submit']} 

.to_dict(flat=False) là điều cần lưu ý. Xem các liên kết documentation

+5

Thay vào đó, hãy sử dụng phương thức '.to_dict()' như 'imd.to_dict()'. Bằng cách đó, mọi giá trị không phải là danh sách, như trong giải pháp của bạn. Ngoài ra, bạn sẽ không cần phải nhập ImmutableMultiDict – wordsforthewise

+1

Tôi có lẽ sẽ cập nhật câu trả lời này để bao gồm những gì bình luận gợi ý làm. Việc sử dụng '.to_dict()' sẽ là cách để đi đến đây để loại bỏ các giá trị đó dưới dạng danh sách.Tôi sẽ giữ câu trả lời của bạn như là, nhưng thêm vào nó và chứng minh sự khác biệt trong việc sử dụng 'to_dict()'. – idjaw

+0

imd.to_dict() không phù hợp vì nó bị mất mục nhập trùng lặp – lod

-2

Một khi bạn có một cuốn từ điển Python, nó là tương đối đơn giản để biến nó thành JSON. Giả sử từ điển của bạn là mdict:

import json 

mdict = {'default' : u'', 'required': u'on', 'name': u'short_text', 'name': u'another', 'submit': u'Submit'} 
json_value = json.dumps(mdict, separators=(',',':')) 

PS: Tôi nghĩ rằng có thể thay đổi dicts có một phương pháp to_dict() để chuyển đổi chúng sang một từ điển thông thường.

15

Bạn có thể sử dụng Werkzeug của getlist để viết mã như thế này

data = dict((key, request.form.getlist(key)) for key in request.form.keys()) 

Bây giờ mỗi chủ chốt của data sẽ là một danh sách mà sẽ chứa 1 phần tử hơn. Để có được kết quả chính xác trong định dạng của bạn làm điều này

data = dict((key, request.form.getlist(key) if len(request.form.getlist(key)) > 1 else request.form.getlist(key)[0]) for key in request.form.keys()) 

Bây giờ điều này là không hiệu quả bởi vì đối với mỗi phím có 3 cuộc gọi đến request.form.getlist(key). Bạn có thể viết một vòng lặp và nhận được xung quanh nó.

13

Cấu trúc dữ liệu Flask ImmutableMultiDict được xây dựng theo phương pháp to_dict.

Kiến thức này ngoài Flask request đối tượng form thuộc tính là ImmutableMultiDict cho phép xử lý đơn giản yêu cầu POST biểu mẫu cho MongoDB.

Xem dưới đây cho một ví dụ ngây thơ:

from flask import request 

@app.route('/api/v1/account', methods=['POST']) 
def create_account(): 
    """Create user account""" 
    account_dict = request.form.to_dict() 

    db.account.insert_one(account_dict) 
9

request.form.to_dict() sẽ mang lại những gì bạn cần

0
>>> from werkzeug.datastructures import ImmutableMultiDict 
>>> so = ImmutableMultiDict([('default', u''), ('required', u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')]) 

# Most earlier answers have comments suggesting so.to_dict() 
# It doesn't work, duplicates are lost like in a normal dict 
>>> so.to_dict() 
{'default': '', 'required': 'on', 'name': 'short_text', 'submit': 'Submit'} 

# The response by Vb407 is better but litters lists everywhere 
>>> dso = dict(so) 
{'default': [''], 'required': ['on'], 'name': ['short_text', 'another'], 'submit': ['Submit']} 

# We can achieve the requested state by cleaning this up 
>>> { k: dso[k][0] if len(dso[k]) <= 1 else dso[k] for k in dso } 
{'default': '', 'required': 'on', 'name': ['short_text', 'another'], 'submit': 'Submit'}