Does Django support multi-value cookies? - python

I'd like to set a cookie via Django with that has several different values to it, similar to .NET's HttpCookie.Values property. Looking at the documentation, I can't tell if this is possible. It looks like it just takes a string, so is there another way?
I've tried passing it an array ([10, 20, 30]) and dictionary ({'name': 'Scott', 'id': 1}) but they just get converted to their string format. My current solution is to just use an arbitrary separator and then parse it when reading it in, which feels icky. If multi-values aren't possible, is there a better way? I'd rather not use lots of cookies, because that would get annoying.

.NETs multi-value cookies work exactly the same way as what you're doing in django using a separator. They've just abstracted that away for you. What you're doing is fine and proper, and I don't think Django has anything specific to 'solve' this problem.
I will say that you're doing the right thing, in not using multiple cookies. Keep the over-the-wire overhead down by doing what you're doing.

If you're looking for something a little more abstracted, try using sessions. I believe the way they work is by storing an id in the cookie that matches a database record. You can store whatever you want in it. It's not exactly the same as what you're looking for, but it could work if you don't mind a small amount of db overhead.

(Late answer!)
This will be bulkier, but you call always use python's built in serializing.
You could always do something like:
import pickle
class MultiCookie():
def __init__(self,cookie=None,values=None):
if cookie != None:
try:
self.values = pickle.loads(cookie)
except:
# assume that it used to just hold a string value
self.values = cookie
elif values != None:
self.values = values
else:
self.values = None
def __str__(self):
return pickle.dumps(self.values)
Then, you can get the cookie:
newcookie = MultiCookie(cookie=request.COOKIES.get('multi'))
values_for_cookie = newcookie.values
Or set the values:
mylist = [ 1, 2, 3 ]
newcookie = MultiCookie(values=mylist)
request.set_cookie('multi',value=newcookie)

Django does not support it. The best way would be to separate the values with arbitrary separator and then just split the string, like you already said.

Related

What kind of data structure is this? Python

Studying Python, I am following an excellent Corey Schafer tutorial on Flask, he does this (I have extracted and summarized it for obvious reasons):
from folder_app import app # I did it to follow the structure and that the code is equal to the original
s = Serializer(app.config['SECRET_KEY'], 1800) # key, seconds
token = s.dumps({'user_id': 1}).decode('utf-8')
s = Serializer(app.config['SECRET_KEY'])
user_id = s.loads(token)['user_id'] # This is where I have the doubt
print(user_id)
print(type(s.loads(token)))
The code works, the problem I have is that although as you can see (s.loads (token)) is a dict, I expected to see something like this s.loads ({token ['user_id']}), or s.loads (token ['user_id']) or something like that. That is, it is a dict but it does not seem so. And my doubt goes in the sense if this comes from a greater concept of those they call "pythonic" (which I have not seen so far), or is something that only happens particularly as in this case. Incidentally, https://itsdangerous.palletsprojects.com/en/1.1.x/jws/ this appears: loads (self, s, salt = None, return_header = False) the arguments are in parentheses. I hope it is clear what my doubt is :)
I know this is not answer per say but just to add to my comment. This is an example of how the loads function works on dictionaries with the json module. https://docs.python.org/3/library/json.html#json.loads. What it does is take a json string and return the dictionary type object in Python. Your Serializer is doing something similar. It takes the token string and represents it as an object like dict
The s.dumps I am assuming is similar to json.dumps which gives you the json string representation of python dictionary.
import json
my_dict = json.loads('{"user_id": "Mane", "name": "Joe"}')
my_dict['user_id']
So you could just do json.loads('{"user_id": "Mane", "name": "Joe"}')['user_id'] which is just chaining the operations.

Python elasticsearch-dsl sorting with multiple fields

I'm trying to form the command for sorting using elasticsearch-dsl. However I have trouble passing the variable in correct format in.
The format should be
s=Search()
s = s.sort({"time":{"order":"asc"}}, {"anoter_field":{"order":"desc"}})
s.execute()
The problem is I'm trying to put {"time":{"order":"asc"}}, {"anoter_field":{"order":"desc"}} as a variable, but I can't seem to get this in the right syntax. I tried using dict, list, and string, and none seems to work.
My input would be a dict that looks like
input = {"time":"asc", "another_field":"desc"}
data_input = {"time":"asc", "another_field":"desc"}
args = [{k:{'order':v}} for k,v in data_input.items()]
s.sort(*args)
I guess is what you are asking? Its hard to tell ...

Representation of python dictionaries with unicode in database queries

I have a problem that I would like to know how to efficiently tackle.
I have data that is JSON-formatted (used with dumps / loads) and contains unicode.
This is part of a protocol implemented with JSON to send messages. So messages will be sent as strings and then loaded into python dictionaries. This means that the representation, as a python dictionary, afterwards will look something like:
{u"mykey": u"myVal"}
It is no problem in itself for the system to handle such structures, but the thing happens when I'm going to make a database query to store this structure.
I'm using pyOrient towards OrientDB. The command ends up something like:
"CREATE VERTEX TestVertex SET data = {u'mykey': u'myVal'}"
Which will end up in the data field getting the following values in OrientDB:
{'_NOT_PARSED_': '_NOT_PARSED_'}
I'm assuming this problem relates to other cases as well when you wish to make a query or somehow represent a data object containing unicode.
How could I efficiently get a representation of this data, of arbitrary depth, to be able to use it in a query?
To clarify even more, this is the string the db expects:
"CREATE VERTEX TestVertex SET data = {'mykey': 'myVal'}"
If I'm simply stating the wrong problem/question and should handle it some other way, I'm very much open to suggestions. But what I want to achieve is to have an efficient way to use python2.7 to build a db-query towards orientdb (using pyorient) that specifies an arbitrary data structure. The data property being set is of the OrientDB type EMBEDDEDMAP.
Any help greatly appreciated.
EDIT1:
More explicitly stating that the first code block shows the object as a dict AFTER being dumped / loaded with json to avoid confusion.
Dargolith:
ok based on your last response it seems you are simply looking for code that will dump python expression in a way that you can control how unicode and other data types print. Here is a very simply function that provides this control. There are ways to make this function more efficient (for example, by using a string buffer rather than doing all of the recursive string concatenation happening here). Still this is a very simple function, and as it stands its execution is probably still dominated by your DB lookup.
As you can see in each of the 'if' statements, you have full control of how each data type prints.
def expr_to_str(thing):
if hasattr(thing, 'keys'):
pairs = ['%s:%s' % (expr_to_str(k),expr_to_str(v)) for k,v in thing.iteritems()]
return '{%s}' % ', '.join(pairs)
if hasattr(thing, '__setslice__'):
parts = [expr_to_str(ele) for ele in thing]
return '[%s]' % (', '.join(parts),)
if isinstance(thing, basestring):
return "'%s'" % (str(thing),)
return str(thing)
print "dumped: %s" % expr_to_str({'one': 33, 'two': [u'unicode', 'just a str', 44.44, {'hash': 'here'}]})
outputs:
dumped: {'two':['unicode', 'just a str', 44.44, {'hash':'here'}], 'one':33}
I went on to use json.dumps() as sobolevn suggested in the comment. I didn't think of that one at first since I wasn't really using json in the driver. It turned out however that json.dumps() provided exactly the formats I needed on all the data types I use. Some examples:
>>> json.dumps('test')
'"test"'
>>> json.dumps(['test1', 'test2'])
'["test1", "test2"]'
>>> json.dumps([u'test1', u'test2'])
'["test1", "test2"]'
>>> json.dumps({u'key1': u'val1', u'key2': [u'val21', 'val22', 1]})
'{"key2": ["val21", "val22", 1], "key1": "val1"}'
If you need to take more control of the format, quotes or other things regarding this conversion, see the reply by Dan Oblinger.

using list instead of number or string in the query

I would like to use a list of int to be used in a query as below:
db.define_table('customer',Field('name'),Field('cusnumber','integer'))
def custmr():
listOfNumbers=[22,12,76,98]
qry=db(db.customer.cusnumber==listOfNumbers).select(db.customer.name)
print qry
this arise an issue that the only accepted data type in the query is int or str.
Is there any way to avoid this issue (preferably by not using for loop)
Regards
It is really difficult to know what you're trying to ask, but from the syntax of db.define_table(...), I take a wild guess you're on web2py and trying to do a query which fetch any int in your listOfNumbers.
You may use contains attribute like this:
# if all=True, cusnumber will need to contains all listOfNumbers, False means any
qry=db(db.customer.cusnumber.contains(listOfNumbers, all=False)).select(db.customer.name)
You can read more in details in HERE
As OP replied that contains only works for string, I'm going to suggest using for/loop will be a better answer:
listOfNumbers=[22,12,76,98]
for each in listOfNumbers:
qry=db(db.customer.cusnumber==each).select(db.customer.name)
# ... do your stuff or whatever ...
Assuming you want the set of records for which the cusnumber is in listOfNumbers, you should use the .belongs method:
qry = db(db.customer.cusnumber.belongs(listOfNumbers)).select(db.customer.name)

StringListProperty limited to 500 char strings (Google App Engine / Python)

It seems that StringListProperty can only contain strings up to 500 chars each, just like StringProperty...
Is there a way to store longer strings than that? I don't need them to be indexed or anything. What I would need would be something like a "TextListProperty", where each string in the list can be any length and not limited to 500 chars.
Can I create a property like that? Or can you experts suggest a different approach? Perhaps I should use a plain list and pickle/unpickle it in a Blob field, or something like that? I'm a bit new to Python and GAE and I would greatly appreciate some pointers instead of spending days on trial and error...thanks!
Alex already answered long ago, but in case someone else comes along with the same issue:
You'd just make item_type equal to db.Text (as OP mentions in a comment).
Here's a simple example:
from google.appengine.ext import db
class LargeTextList(db.Model):
large_text_list = db.ListProperty(item_type=db.Text)
def post(self):
# get value from a POST request,
# split into list using some delimiter
# add to datastore
L = self.request.get('large_text_list').split() # your delimiter here
LTL = [db.Text(i) for i in L]
new = LargeTextList()
new.large_text_list = LTL
new.put()
def get(self):
# return one to make sure it's working
query = LargeTextList.all()
results = query.fetch(limit=1)
self.render('index.html',
{ 'results': results,
'title': 'LargeTextList Example',
})
You can use a generic ListProperty with an item_type as you require (str, or unicode, or whatever).

Categories

Resources