Идентификатор объекта отсутствует в платформе Django при публикации из AngularJS MongoDB - PullRequest
0 голосов
/ 29 апреля 2018

Я размещаю следующий объект

{
    skillName : "Professional Skills"
    _id : {$oid: "5adf23946ab671bf6cb36aff"}
    }

к DjangoService, указанному ниже:

@csrf_exempt
@api_view(['GET','POST'])
def saveSubjectView(request):  #this service will add & update Subject

    if request.method == 'POST':
        try:
            stream = StringIO(request.body)
            subject = JSONParser().parse(stream)
            print("The subejct is ")
            pp.pprint(subject)
            serializedsubject = json.loads(json_util.dumps(subject))
            print("serializedsubject")
            pp.pprint(serializedsubject)

Я получаю вывод

'skillType': {   u'_id': {   }, u'skillName': u'Professional Skills'}

ObjectId, отправленный из внешнего интерфейса (AngularJS), не печатается в сервисе. Я знаю, что могу это исправить, удалив $ oid при публикации из приложения AngularJS. Но я хотел бы знать, почему этого не происходит. Я искал документы и не смог получить правильный ответ. Может быть, ключевые слова, которые я использовал, неверны. Используемые ключевые слова: «Сериализация JSON ObjectId», «Сериализация $ oid json с использованием Django».

Полный объект, который я публикую в сервисе Django, приведен ниже:

enter image description here

1 Ответ

0 голосов
/ 29 апреля 2018

Точно. $oid или что-либо с префиксом $ является внутренним форматом и зарезервировано, поэтому вы не можете публиковать имена полей. Соглашение взято из MongoDB Extended JSON , где такие префиксы используются для идентификации типа BSON для правильного преобразования и используются в качестве сериализуемого транспорта, поскольку эти "типы" не поддерживаются в базовом JSON.

Таким образом, решение состоит в том, чтобы фактически использовать bson.json_util для "десериализации" строки JSON с самого начала:

from bson import json_util

# serializedsubject = json.loads(json_util.dumps(subject))
serializedsubject = json_util.loads(request.body)     # correct usage

Или более кратко самодостаточно:

input = '{ "skillName" : "Professional Skills" ,"_id" : { "$oid": "5adf23946ab671bf6cb36aff"} }'
json_util.loads(input)

Возвращает

{u'skillName': u'Professional Skills', u'_id': ObjectId('5adf23946ab671bf6cb36aff')} 

Это корректно преобразует объекты из любых ключей, помеченных расширенным синтаксисом JSON, в их правильный тип BSON, что также поддерживается в функциях драйвера. И, естественно, драйвер будет преобразован обратно в BSON при отправке в MongoDB.

Если по какой-то причине ваш request.body содержит что-то кроме «строки», которая является допустимой для ввода в функцию, то ваш код должен преобразовать ее в эту точку. Но не должно быть необходимости "анализировать в JSON", а затем снова "stringify" только для ввода в функцию.


ПРИМЕЧАНИЕ : Если вы еще не сделали этого на клиентской стороне JavaScript приложения, доступен также пакет bson. Это позволило бы, где такой расширенный JSON «получен» от сервера, преобразовать в типы BSON как объекты JavaScript и, конечно, затем сериализовать такие объекты обратно в расширенный формат JSON.

Это на самом деле было бы рекомендовано, когда необходимо поддерживать информацию «типа» вместе с данными, передаваемыми и хранящимися между клиентом и сервером.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...