- Author:
- SpikeekipS
- Posted:
- March 11, 2008
- Language:
- Python
- Version:
- .96
- Score:
- 2 (after 2 ratings)
Django supports the serializing model objects, but does not support the serializing Q object like that,
q = Q(username__contains="findme") model0.objects.filter(q)
serialize(q) # X
so I wrote a little marshaller for Q, this is example,
from django.contrib.auth import models as django_models qs = django_query.Q(usernamecontains="spike") | django_query.Q(emailcontains="spike")
_m = QMarshaller() a = _m.dumps(qs) # a was serialized.
When call the similiar queries in page by page, you don't need to write additional code for creating same Q(s) for filtering models, just use the serialized Q as http querystring and in the next page unserialize and apply it. That is simple life.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | # -*- coding: utf-8 -*-
import base64, string
from xml.marshal.generic import Marshaller, Unmarshaller
from django.db.models import Model
from django.db.models.loading import get_model
from django.db.models import query as django_query
from copy import copy
class QMarshaller (Marshaller) :
def dumps (self, value, use_base64=False) :
o = Marshaller.dumps(self, value)
if use_base64 :
return base64.b64encode(o)
else :
return o
def _marshal(self, value, dict):
if isinstance(value, Model) :
meth = "m_django_object"
return getattr(self, meth)(value, dict)
return Marshaller._marshal(self, value, dict)
def m_unicode (self, value, dict) :
return self.m_string(value.encode("utf8"), dict)
def m_django_object (self, object, dict) :
name = "django_object"
model_name = "%s.%s" % (object._meta.app_label, object._meta.module_name, )
L = ["<%s model=\"%s\" pk=\"%s\">" % (name, model_name, object.pk)]
L.append("</%s>" % name)
return L
def m_condition (self, c, dict, ) :
name = "condition"
k, v, = c
L = ["<%s key=\"%s\">" % (name, k, )]
L = L + self._marshal(v, dict)
L.append("</%s>" % name)
return L
def m_Q (self, q, dict, ) :
name = "Q"
L = ["<%s>" % (name, )]
for c in q.kwargs.items() :
L = L + self.m_condition(c, dict)
L.append("</%s>" % name)
return L
def m_QOr (self, q, dict, ) :
name = "QOr"
L = ["<%s operator=\"%s\">" % (name, q.operator.strip(), )]
for elem in q.args :
L = L + self._marshal(elem, dict)
L.append("</%s>" % name)
return L
def m_QAnd (self, q, dict, ) :
name = "QAnd"
L = ["<%s operator=\"%s\">" % (name, q.operator.strip(), )]
for elem in q.args :
L = L + self._marshal(elem, dict)
L.append("</%s>" % name)
return L
class QUnmarshaller (Unmarshaller) :
def __init__(self):
self.unmarshal_meth.update(
{
"django_object": ("um_start_django_object", "um_end_django_object", ),
"condition": ("um_start_condition", "um_end_condition", ),
"Q": ("um_start_Q", "um_end_Q", ),
"QOr": ("um_start_QOr", "um_end_QOr", ),
"QAnd": ("um_start_QAnd", "um_end_QAnd", ),
}
)
Unmarshaller.__init__(self)
def loads (self, s, use_base64=False) :
if use_base64 :
s = base64.b64decode(s)
return Unmarshaller.loads(self, s)
def um_end_string(self, name):
ds = self.data_stack
ds[-1] = string.join(ds[-1], "").encode("utf8")
def um_start_QOr (self, name, attrs) :
pass
def um_end_QOr (self, name) :
q = django_query.QOr()
for i in self.data_stack :
q = q | i
self.data_stack[:] = [q]
def um_start_QAnd (self, name, attrs) :
pass
def um_end_QAnd (self, name) :
q = django_query.QAnd()
for i in self.data_stack :
q = q & i
self.data_stack[:] = [q]
def um_start_Q (self, name, attrs) :
pass
def um_end_Q (self, name) :
if len(self.data_stack) < 1 :
self.data_stack.append(django_query.Q())
else :
key, value, = self.data_stack[-1]
self.data_stack[-1] = django_query.Q(**{str(key): value})
def um_start_condition (self, name, attrs) :
self.data_stack.append(attrs.get("key"), )
def um_end_condition (self, name) :
key, value, = self.data_stack[-2:]
self.data_stack[-2:] = [(key, value, )]
def um_start_django_object (self, name, attrs) :
m = get_model(*attrs.get("model").split("."))
self.data_stack.append(m.objects.get(pk=attrs.get("pk")))
def um_end_django_object (self, name) :
pass
if __name__ == "__main__" :
import sys, base64
from django.contrib.auth import models as django_models
qs = django_query.Q(username__contains="spike") | django_query.Q(email__contains="spike")
_m = QMarshaller()
a = _m.dumps(qs)
print "Marshalled:"
print a
print
_u = QUnmarshaller()
qs = _u.loads(a)
print "UnMarshalled:"
print qs
for i in qs.args :
print i.kwargs
print
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.