Jsonfield django как использовать
Перейти к содержимому

Jsonfield django как использовать

  • автор:

Как правильно прописать json структуру в models.py проекта django с помощью JSONField?

БД моего проекта — MongoDB, для соединения mongo и проекта django (использую версию 4.0.1) я использую движок «djОngo». Соединение с базой работает корректно.
Я хочу хранить в MongoDB данные, получаемые из внешнего API либо записанные через форму на странице сайта, которые могут иметь вложенные списки, или иногда вложенные объекты.
Пример json структуры которая будет записываться через форму и приходить по API:

"FormsID": 1, "make": < "1_new": 21, "2_new": 16, "right": 80, "left": 10, >, "static": [ < "name": " 1", "number": 1, "id":93, "day": < "start": 7, "end": 23,>>]

На данный момент задача реализована частично, объясняю. Мой файл models.py:

from djongo import models class StaticForms(models.Model): FormsID=models.ObjectIdField(primary_key=True) make = models.JSONField() static=models.JSONField() day=models.JSONField()

Далее уже в файле views.py я добавляю нужные ключи уже в make, static и day.
Мой файл views.py:

from django.views.decorators.csrf import csrf_exempt from django.http.response import JsonResponse, HttpResponse from FirstApp.models import StaticForms @csrf_exempt def forms_post(request): make = static = day = post = StaticForms(FormsID=request.POST.get("FormsID"), make=make, static=static, day=day) post.save() return HttpResponse("Inserted")

После добавления данных через Postman я получаю следующую JSON структуру. (отличается от требуемой):

"make": < "1_new": 21, "2_new": 16, "right": 80, "left": 10, >, "static": < "name": " 1", "number": 1, "id":93>"day":

1) Как мне вложить dict «day» в dict «static» чтобы получилось, как в моем первом примере?
2) почему отсутствует поле «FormsID»?

  • Вопрос задан более года назад
  • 191 просмотр

JSONField и кириллица в django

Это безопасный формат. Так url в вебе формируют, в отличие от iri, в котором разрешён utf-8. Только если переопределять и допиливать сам jsonfield. Можно просто обратную конвертацию сделать.

1 июн 2017 в 18:14

Не работайте с json на прямую. Есть хорошие варианты редакторов для таких полей. По вопросу. Это стандарт для json, если его не нарушать, то никак. Если преобразуете, то в базе у вас уже будет храниться не json, а что-то похожее.

1 июн 2017 в 18:30

@Igor стандарт для JSON — UTF-8, выводить кириллицу (и другие нетехнические символы) как есть вполне разрешает RFC 7159

4 июн 2017 в 9:54

@andreymal, согласен. Но в стандарте так же указано, что необходимо для совместимости. По редакторам, возможно использовать например github.com/paytm/dj-j-ka-bachcha-field, чтобы не полностью руками редактировать.

5 июн 2017 в 0:28

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

import json from pygments import highlight from pygments.lexers import JsonLexer from pygments.formatters import HtmlFormatter from django.contrib import admin from django.utils.safestring import mark_safe from .models import Some @admin.register(Some) class SomeAdmin(admin.ModelAdmin): fields = ('items_prettified',) readonly_fields = ('items_prettified',) def items_prettified(self, instance): # Преобразуем данные поля в юникод-строку с отступами json_str = json.dumps(instance.items, sort_keys=True, indent=2, ensure_ascii=False) # Обрезаем, если строка слишком длинная json_str = json_str[:5000] # Добавляем подсветку синтаксиса formatter = HtmlFormatter(style='colorful') output = highlight(json_str, JsonLexer(), formatter) style = "
" return mark_safe(style + output) items_prettified.allow_tags = True items_prettified.short_description = Some._meta.get_field('items').verbose_name.title()

Отслеживать
ответ дан 4 июн 2017 в 8:52
Sergey Gornostaev Sergey Gornostaev
66.3k 6 6 золотых знаков 51 51 серебряный знак 112 112 бронзовых знаков

Можно воспользоваться предыдущим решением, но тогда у нас будет два поля в админке: одно с кириллицей, второе в кодировке. Я нашел такое решение:

  1. Создаём файл utils.py в папке с приложением и вставляем в него следующее:
import json from django.contrib.postgres.forms.jsonb import InvalidJSONInput, JSONField class ReadableJSONFormField(JSONField): def prepare_value(self, value): if isinstance(value, InvalidJSONInput): return value return json.dumps(value, ensure_ascii=False, indent=4)
  1. Заходим в admins.py и «перезаписываем» поле.
from django.contrib import admin from django.contrib.postgres.fields import JSONField from .utils import ReadableJSONFormField from .models import Some @admin.register(Some) class SomeAdmin(admin.ModelAdmin): formfield_overrides = < JSONField: , >

Желательно именно прописывать ReadableJSONFormField в utils.py, тк если прописать в админке его, то не у меня работает через раз.

О Python с Игорем Давыденко

Всякое разное о Python, раньше было про Django/Flask, сейчас больше про Fast Python и asyncio.

13 февраля 2009 г.

Простой и работающий JSONField для Django

Не успел, я починить PickleField для Django, мне понадобилось создать JSONField . Задача оказалась решенной на раз/два, плюс ко всему добавился маленький и полезный виджет для JSONField ‘а, который показывает красиво отформатированный JSON в textarea . Сразу скажу, что contribute_to_class метод чуть менне, чем полностью, скопипастен с снипетта 377.

from django.conf import settings from django.forms.widgets import Textarea from django.db.models import SubfieldBase, TextField from django.utils import simplejson class JSONField(TextField): __metaclass__ = SubfieldBase def contribute_to_class(self, cls, name): super(JSONField, self).contribute_to_class(cls, name) def get_json(model): return self.get_db_prep_value(getattr(model, self.attname)) setattr(cls, 'get_%s_json' % self.name, get_json) def set_json(model, json): setattr(model, self.attname, self.to_python(json)) setattr(cls, 'set_%s_json' % self.name, set_json) def formfield(self, **kwargs): kwargs['widget'] = JSONWidget(attrs=) return super(JSONField, self).formfield(**kwargs) def get_db_prep_value(self, value): return simplejson.dumps(value) def to_python(self, value): if not isinstance(value, basestring): return value try: return simplejson.loads(value, encoding=settings.DEFAULT_CHARSET) except ValueError, e: # If string could not parse as JSON it's means that it's Python # string saved to JSONField. return value class JSONWidget(Textarea): """ Prettify dumps of all non-string JSON data. """ def render(self, name, value, attrs=None): if not isinstance(value, basestring) and value is not None: value = simplejson.dumps(value, indent=4, sort_keys=True) return super(JSONWidget, self).render(name, value, attrs)

Ну и пару примеров использования, напоследок:

>>> # Пусть у нас есть простая модель >>> class Sample(models.Model): . name = models.CharField(max_length=16) . data = JSONField() >>> # Создадим модель и сохраним в data поле настройки для ShadowBox >>> sb = Sample.objects.create(name='ShadowBox', . data=) >>> # Теперь мы хотим напечатать эти настройки где-то в шаблоне >>> sb.get_data_json() '' >>> # Вспомним, что нам вообщем-то не зачем кастомное значение для overlayOpacity >>> del sb.data['overlayOpacity'] >>> sb.save() >>> # И опять напечатаем настройки в шаблоне >>> sb.get_data_json() ''

зы. ShadowBox — это лучший лайтбокс для любого JavaScript фреймворка, имо.

Простой и работающий JSONField для Django

Не успел, я починить PickleField для Django, мне понадобилось создать JSONField . Задача оказалась решенной на раз/два, плюс ко всему добавился маленький и полезный виджет для JSONField ‘а, который показывает красиво отформатированный JSON в textarea . Сразу скажу, что contribute_to_class метод чуть менне, чем полностью, скопипастен с снипетта 377.

from django.conf import settings from django.forms.widgets import Textarea from django.db.models import SubfieldBase, TextField from django.utils import simplejson class JSONField(TextField): __metaclass__ = SubfieldBase def contribute_to_class(self, cls, name): super(JSONField, self).contribute_to_class(cls, name) def get_json(model): return self.get_db_prep_value(getattr(model, self.attname)) setattr(cls, 'get_%s_json' % self.name, get_json) def set_json(model, json): setattr(model, self.attname, self.to_python(json)) setattr(cls, 'set_%s_json' % self.name, set_json) def formfield(self, **kwargs): kwargs['widget'] = JSONWidget(attrs=) return super(JSONField, self).formfield(**kwargs) def get_db_prep_value(self, value): return simplejson.dumps(value) def to_python(self, value): if not isinstance(value, basestring): return value try: return simplejson.loads(value, encoding=settings.DEFAULT_CHARSET) except ValueError, e: # If string could not parse as JSON it's means that it's Python # string saved to JSONField. return value class JSONWidget(Textarea): """ Prettify dumps of all non-string JSON data. """ def render(self, name, value, attrs=None): if not isinstance(value, basestring) and value is not None: value = simplejson.dumps(value, indent=4, sort_keys=True) return super(JSONWidget, self).render(name, value, attrs)

Ну и пару примеров использования, напоследок:

>>> # Пусть у нас есть простая модель >>> class Sample(models.Model): . name = models.CharField(max_length=16) . data = JSONField() >>> # Создадим модель и сохраним в data поле настройки для ShadowBox >>> sb = Sample.objects.create(name='ShadowBox', . data=) >>> # Теперь мы хотим напечатать эти настройки где-то в шаблоне >>> sb.get_data_json() '' >>> # Вспомним, что нам вообщем-то не зачем кастомное значение для overlayOpacity >>> del sb.data['overlayOpacity'] >>> sb.save() >>> # И опять напечатаем настройки в шаблоне >>> sb.get_data_json() ''

зы. ShadowBox — это лучший лайтбокс для любого JavaScript фреймворка, имо.

Django JSONField: руководство по эффективной обработке данных

Play video

Новое поле JSONField в Django позволяет вам использовать JSON в любой базе данных, даже если база данных изначально не поддерживает JSON.

Django автоматически преобразует данные JSON в объект словаря, упрощая взаимодействие с данными и манипулирование ими.

При использовании JSONField в Django важно обеспечить согласованность передаваемых данных для поддержания структуры и целостности базы данных.

Хранение пользовательских настроек в виде объекта JSON в базе данных может быть более эффективным и удобным способом загрузки и извлечения данных конфигурации для интерфейсного приложения.

Summarize any YouTube video by yourself

Download on the App Store

Desktop options: Safari Chrome

Summarize any YouTube video by yourself

Other options: iOS App Chrome

Summarize any YouTube video by yourself

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *