POSTAGEM de Angular para Django

Se você estiver usando Django e AngularJS, provavelmente terá o problema de tentar fazer o POST de dados no Djan. Por exemplo,

$http({
url
: "<myawesomeview>",
method
: 'POST',
data
: { 'text': 'this is really important', 'date': '2014-06-09'}
})

O problema que surge é que o padrão do AngularJS é enviar dados JSON no corpo da resposta em vez de dados codificados por url, que é o tipo de dados que o Django está procurando. Como resultado, de volta ao Django, se fizéssemos o seguinte

def myawesomeview(request):
print request.POST
print request.body

Nós conseguiríamos

<QueryDict: {}>
u"{ 'text': 'this is really important', 'date': '2014-06-09'}"

de volta em nosso console. Se você usa Django há um pouco, então percebe que realmente esperávamos

<QueryDict: {u'text': u'this is really important', u'date': u'2014-06-09'}>
u"{ 'text': 'this is really important', 'date': '2014-06-09'}"

Você pode encontrar minha solução para isso nesta essência , que é gentilmente fornecida abaixo:

ATUALIZAÇÃO Eu encontrei um bug em minha versão anterior, eu o atualizei para resolver isso, o problema principal era como o valor da lista estava sendo tratado.

class JSONMiddleware(object):
"""
Process application/json requests data from GET and POST requests.

"""

def process_request(self, request):
if 'application/json' in request.META['CONTENT_TYPE']:
# load the json data
data
= json.loads(request.body)
# for consistency sake, we want to return
# a Django QueryDict and not a plain Dict.
# The primary difference is that the QueryDict stores
# every value in a list and is, by default, immutable.
# The primary issue is making sure that list values are
# properly inserted into the QueryDict. If we simply
# do a q_data.update(data), any list values will be wrapped
# in another list. By iterating through the list and updating
# for each value, we get the expected result of a single list.
q_data
= QueryDict('', mutable=True)
for key, value in data.iteritems():
if isinstance(value, list):
# need to iterate through the list and upate
# so that the list does not get wrapped in an
# additional list.
for x in value:
q_data
.update({key: x})
else:
q_data
.update({key: value})

if request.method == 'GET':
request
.GET = q_data

if request.method == 'POST':
request
.POST = q_data

return None

A velha versão ingênua

class JSONMiddleware(object):
"""
Process application/json requests data from GET and POST requests.

"""

def process_request(self, request):
if 'application/json' in request.META['CONTENT_TYPE']:
data
= urlencode(json.loads(request.body))

if request.method == 'GET':
request
.GET = QueryDict(data)

if request.method == 'POST':
request
.POST = QueryDict(data)

return None

Se você adicionar esse middleware à instalação do Django, ele processará os dados JSON e os colocará na variável GET ou POST conforme apropriado. Existem, é claro, outras soluções para este problema, mas usar este middleware permite que você escreva suas views em AngularJS ou Django como pretendido, passando um objeto como dados e lendo de request.POST.