سؤال

my problem is that I have to encode a dict to make a couchdb design:

I have this dict:

params = {'descending': 'true', 'startkey': 'Mexico', 'endkey': 'Mexico'}

I want a URL like this:

http://localhost:5984/hello-world/_design/precios/_view/precios?descending=true&startkey=%22Mexico%22&endkey=%22Mexico%22

or like this:

http://localhost:5984/hello-world/_design/precios/_view/precios?descending=true&startkey="Mexico"&endkey="Mexico"

So I use urllib.urlencode to convert the dict into a query string:

urllib.urlencode(params)

This one returns me something like:

http://localhost:5984/hello-world/_design/precios/_view/precios?descending=true&startkey=Mexico&endkey=Mexico

So This is an invalid URL for CouchDB because CouchDB requires the double quotes in startkey and endkey

If I change my dict for something like:

params = {'descending': 'true', 'startkey': '"Mexico"', 'endkey': '"Mexico"'}

This one returns a valid URL like this:

http://localhost:5984/hello-world/_design/precios/_view/precios?descending=true&startkey=%22Mexico%22&endkey=%22Mexico%22

But I do not want to pass the double quotes inside the single quotes, is there a way to do this that returns me a valid URL?

Thanks for your answers :D

هل كانت مفيدة؟

المحلول

Couch parameter values are JSON literals, so should be created by JSON-encoding the values. Then you need to URL-encode the results of that to fit in a standard URL, as well.

Example:

import urllib, json
def to_json_query(params):
    return urllib.urlencode({p: json.dumps(params[p]) for p in params})

>>> qs = to_json_query({'descending': True, 'startkey': 'Mexico', 'endkey': 'Mexico'})
'startkey=%22Mexico%22&endkey=%22Mexico%22&descending=%22true%22'

Note I have changed the value of descending to be a boolean True, as you want a JSON boolean true and not the string "true".

(The existing answers here assume string and don't URL-encode or JSON-encode, so will fail for any JSON-special or URL-special characters, any non-ASCII or non-string datatype.)

نصائح أخرى

I would suggest writing your own urlencode function. Here's a basic example :

params = {"startkey":"Mexico","endkey":"Mexico"}

def myencode(params):
    return "&".join(['%s="%s"' %(key,value) for key,value in params.iteritems()])

print myencode(params)

## chaouche@karabeela ~/CODE/TEST/PYTHON $ python test_exec_minimal2.py
## startkey="Mexico"&endkey="Mexico"
## chaouche@karabeela ~/CODE/TEST/PYTHON $
params = {'descending': 'true', 'startkey': 'Mexico', 'endkey': 'Mexico'}
pairs = ['{}="{}"'.format(k,v) for k,v in params.items()]

print '&'.join(pairs);

--output:--
startkey="Mexico"&endkey="Mexico"&descending="true"

If you don't want true to be quoted, then do the same thing in a for-loop, and don't quote true.

Double quotes aren't allowed in query strings, so you'd better use:

pairs = ['{}=%22{}%22'.format(k,v) for k,v in params.items()]
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top