2012-11-23 3 views
11

Sto usando Flask e MongoDB. Sto cercando di convertire il contenuto di request.form in qualcosa di adatto per il salvataggio tramite PyMongo. Sembra qualcosa che dovrebbe apparire abbastanza spesso per avere una soluzione pronta.In Flask convertire l'oggetto POST in una rappresentazione adatta per mongodb

Allora, cosa Flask dammi è qualcosa di simile:

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

E quello che sto cercando di ottenere è qualcosa di simile a questo:

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

Perché avete bisogno di questo? è possibile accedere ai valori mentre si accede al dizionario senza convertirlo. come d ['required'] ti restituisce true. –

+0

@Abdul, se si desidera eseguire il ciclo attraverso ImmutableNutiDict(), allora si può fare come normalmente il dizionario, ma se si desidera usarlo nel suo insieme come un dict, ad esempio, unire il dizionario usando z = {** x, ** y}, quindi non funziona, il valore avrà quadrati attorno ad esso, come {..., 'nome': ['short_text'],}. – zhihong

risposta

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) è la cosa da tenere a mente. Vedere il relativo documentation

+5

Usa invece il metodo '.to_dict()' come 'imd.to_dict()'. In questo modo ogni valore non è una lista, come nella tua soluzione. Inoltre non sarà necessario importare ImmutableMultiDict – wordsforthewise

+1

Probabilmente aggiornerei questa risposta per includere ciò che il commento suggerisce di fare. L'uso di '.to_dict()' sarebbe il modo di andare qui per rimuovere quei valori come liste.Vorrei mantenere la tua risposta così com'è, ma aggiungerla e dimostrare la differenza nell'usare 'to_dict()'. – idjaw

+0

imd.to_dict() non è appropriato in quanto perde la voce duplicata – lod

-2

Una volta che avete un dizionario Python, è relativamente semplice da trasformare in JSON. Supponendo il dizionario è 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: Penso dicts mutevoli hanno un metodo to_dict() per convertirli in un normale dizionario.

15

È possibile utilizzare werkzeug di getlist di scrivere codice come questo

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

Ora ogni tasto di data sarebbe una lista che conterrebbe 1 altro elemento. Per ottenere i risultati esattamente nel formato fanno

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()) 

Ora, questo è inefficiente perché per ogni chiave ci sono 3 chiamate a request.form.getlist(key). Puoi scrivere un ciclo e aggirarlo.

13

La struttura dati del matraccio ImmutableMultiDict ha un metodo integrato to_dict.

Questa conoscenza in aggiunta al Flacone oggetto form proprietà è un ImmutableMultiDict consente la semplice gestione di una richiesta POST modulo a MongoDB.

Vedi sotto per un esempio di ingenuo:

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() produrrebbe ciò che è necessario

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'} 
Problemi correlati