- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试通过将某些对象存储在 JSONFields 中来对支持 JSON API 的 Django Postgres 数据库进行去规范化:
https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/fields/#jsonfield
我扩展了 django.contrib.postgres.fields.JSONField 字段以自动将数据序列化为 Python 对象。我这样做是为了围绕对象封装我的逻辑并强制执行存储在 JSONField 中的对象的结构。我在这里关注自定义模型字段的 Django 文档:
https://docs.djangoproject.com/en/1.11/howto/custom-model-fields/
我可以将我的对象存储在自定义 JSONField 中,并可以将它们作为 native Python 对象检索,但是,我破坏了管理控制台。当我尝试查看我的一个对象时,出现此错误:
TypeError: <core.fields.PostalAddress object at 0x7fdcfaade4e0> is not JSON serializable
我认为问题是内置的 json.dumps 函数不能很好地处理随机对象,所以我希望我可以在我的 PostalAddress 类中重写一些方法来让它很好地播放。
这是我的代码,虽然这是一个简单的地址案例,但我想将此模式应用于更复杂和有用的自定义 JSONField 用例,所以我希望在管理控制台中看到序列化的 JSON 并且能够编辑文本并保存。
字段.py
from django.contrib.postgres.fields import JSONField
class PostalAddress(object):
def __init__(self, street='', city='', state='', postal_code=''):
self.street = street
self.city = city
self.state = state
self.postal_code = postal_code
def deserialize_address(address_dict):
return PostalAddress(**address_dict)
def get_empty_address():
return PostalAddress()
class PostalAddressField(JSONField):
description = "A postal address"
def __init__(self, *args, **kwargs):
super(PostalAddressField, self).__init__(*args, **kwargs)
def get_prep_value(self, value):
if value is None:
return value
if isinstance(value, PostalAddress):
return json.dumps(value.__dict__)
return value
def from_db_value(self, value, expression, connection, context):
if value is None:
return value
return deserialize_address(value)
def to_python(self, value):
if isinstance(value, PostalAddress):
return value
if value is None:
return value
return deserialize_address(value)
模型.py
from django.db import models
from .fields import PostalAddressField, get_empty_address
class Person(models.Model):
shipping_address = PostalAddressField(default = get_empty_address)
完整跟踪:
Request Method: GET
Request URL:...
Django Version: 1.11.6
Python Version: 3.5.2
Installed Applications:
['grappelli',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.postgres',
'rest_framework',
'rest_framework.authtoken',...
]
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template /home/ubuntu/venv/lib/python3.5/site-packages/grappelli/templates/admin/includes/fieldset.html, error at line 24
<core.fields.PostalAddress object at 0x7f2c7fc085f8> is not JSON serializable 14 : {% if field.is_checkbox %}
15 : <div class="c-1"> </div>
16 : <div class="c-2">
17 : {{ field.field }}{{ field.label_tag|prettylabel }}
18 : {% else %}
19 : <div class="c-1">{{ field.label_tag|prettylabel }}</div>
20 : <div class="c-2">
21 : {% if field.is_readonly %}
22 : <div class="grp-readonly">{{ field.contents }}</div>
23 : {% else %}
24 : {{ field.field }}
25 : {% endif %}
26 : {% endif %}
27 : {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
28 : {% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.field.errors }}{% endif %}
29 : {% if field.field.help_text %}
30 : <p class="grp-help">{{ field.field.help_text|safe }}</p>
31 : {% endif %}
32 : </div>
33 : </div>
34 : {% endfor %}
Traceback:
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
217. response = self.process_exception_by_middleware(e, request)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
215. response = response.render()
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/response.py" in render
107. self.content = self.rendered_content
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/response.py" in rendered_content
84. content = template.render(context, self._request)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/backends/django.py" in render
66. return self.template.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
207. return self._render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
177. return compiled_parent._render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
177. return compiled_parent._render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
72. result = block.nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
72. result = block.nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/defaulttags.py" in render
216. nodelist.append(node.render_annotated(context))
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
216. return template.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
209. return self._render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/defaulttags.py" in render
411. return strip_spaces_between_tags(self.nodelist.render(context).strip())
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/defaulttags.py" in render
216. nodelist.append(node.render_annotated(context))
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/defaulttags.py" in render
216. nodelist.append(node.render_annotated(context))
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/defaulttags.py" in render
322. return nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/defaulttags.py" in render
322. return nodelist.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render
1046. return render_value_in_context(output, context)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/template/base.py" in render_value_in_context
1024. value = force_text(value)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/utils/encoding.py" in force_text
76. s = six.text_type(s)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/utils/html.py" in <lambda>
385. klass.__str__ = lambda self: mark_safe(klass_str(self))
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/forms/boundfield.py" in __str__
40. return self.as_widget() + self.as_hidden(only_initial=True)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/forms/boundfield.py" in as_widget
125. value=self.value(),
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/forms/boundfield.py" in value
162. return self.field.prepare_value(data)
File "/home/ubuntu/venv/lib/python3.5/site-packages/django/contrib/postgres/forms/jsonb.py" in prepare_value
55. return json.dumps(value)
File "/usr/lib/python3.5/json/__init__.py" in dumps
230. return _default_encoder.encode(obj)
File "/usr/lib/python3.5/json/encoder.py" in encode
198. chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.5/json/encoder.py" in iterencode
256. return _iterencode(o, 0)
File "/usr/lib/python3.5/json/encoder.py" in default
179. raise TypeError(repr(o) + " is not JSON serializable")
Exception Type: TypeError at /admin/...
Exception Value: <core.fields.PostalAddress object at 0x7f2c7fc085f8> is not JSON serializable
最佳答案
您遇到的问题是 Django 使用它的 JSONField
form field尝试反序列化管理员中的对象 - 这失败了,因为它仅使用 json.dumps()
无法处理您的 PostalAddress
对象。
您已经覆盖了 model 字段,但您还需要覆盖管理中使用的 form 字段。该文档描述了如何 specify a custom form field for a model field .
像这样:
from django.contrib.postgres.forms import JSONField
# Define a new form field
class PostalAddressJSONField(JSONField):
def prepare_value(self, value):
# Here, deserialize the object in a way that works.
# I've copied what you've done in your model field.
return json.dumps(value.__dict__)
然后在您的 PostalAddressField
中指定这个新的表单字段:
class PostalAddressField(JSONField):
def formfield(self, **kwargs):
defaults = {'form_class': PostalAddressJSONField}
defaults.update(kwargs)
return super().formfield(**defaults)
ModelAdmin
表单现在应该使用这个自定义表单字段,并且能够正确反序列化它。
关于Django 管理员 : object is not JSON serializable error on Custom Field Sub-classing JSONField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47116153/
我只想知道它们之间的区别: .class .class{ font-size:14px; } 对比: .class > .class{ font-size:14px; } 是一样的东西吗? 最佳答案
PrimeFaces 文档的以下摘录使标题中描述的两个选择器之间似乎存在差异: .ui-widget, .ui-widget .ui-widget { font-size: 90% !imp
我正在尝试选择特定值。但我遇到了一个问题。 我有两个元素,一个有 X Y,另一个有 X Y Z。 当选择 X Y Z 时,我也收到 X Y 的值...有没有办法让它寻找 X AND Y AND Z 而
.class.class 和 .class .class 有什么区别? 最佳答案 .class .class 匹配类 .class 的任何元素,这些元素是类 .class< 的另一个元素的后代/. .
我正在研究 Classname.class 和 Classname.class.toString() 并发现了一些不寻常的东西。 .class 在同一个类上运行时似乎等同于 .class。尽管 .cl
我试图在Dart中扩展列表并在此列表中使用另一个类。 这是我的示例,其中注释出了问题: import "Radio.dart"; // extends ListBase { List ra
我有一个很大的“经理”类,我认为它做得太多了,但我不确定如何将它划分为更多逻辑单元。 一般来说类主要由以下方法组成: class FooBarManager{ GetFooEntities();
我在一个文件中定义了一个抽象父类(super class),在另一个文件中定义了一个子类。我需要父类(super class)文件和堆栈跟踪报告来找到一个包含它。 但是,当它到达“extends”行时
我在 A. Alexenderscu 的现代 C++ 设计中找到了一些模板示例 作者使用以下行的地方 template class CheckingPolicy // class SmartPt
看一下这段代码: public static class A { public void doA() { } } public static class B extends A {
我有两个具有 .body 类的 div,但是,一个位于另一个具有 .box 类的 div 中 - 如下所示: 我只想为 .box 内部的 .body 设置样式...但我在下面所
我一定是遗漏了 C++ 规范中的某些内容,因为我无法解释为什么以下代码可以成功编译: class MyClass { static void fun(); }; int main() { MyClas
我正在尝试在 python 中“模拟”命名空间。我使用内部和外部类层次结构来创建我的命名空间。例如,您希望将文件(如资源)的路径保存在一个位置。我试过这样的事情: src = #path to sou
在试验 online crystal compiler 时(这太棒了),我遇到了一个我似乎无法找到解释的错误: class Person class Current < self end
在查看我的一段代码时,我陷入了如下的一条语句。 TMyObjectClass = TMyObject 类; 我有点困惑,不知道这句话是什么意思。由于 TMyObjectClass 在该语句上方没有声明
我正在编写一个简单的应用程序,以学习一些基本的Dart编程,但无法弄清楚其结构和包含的内容-我得到了一个重复的类Point 首先,我有一个叫做MouseTrack的主类。它将初始化列表并产生循环。 #
在 org.springframework.core.SerializableTypeWrapper (版本 5.2.3),第 112 行有以下代码: if (GraalDetector.in
我希望将鼠标悬停在子导航中的列表项上,以激活页面上该类别中所有项的类(不仅仅是父元素或同级元素)。有任何想法吗?这是我的意思的一个例子: img.BLUE {border:1px solid #FF
我正在通过 ClassLoader 加载类: Class clazz = urlClassLoader.loadClass(name.substring(0, name.length() - 6).r
以下简化的类在从 get() 返回值时执行不同的操作,具体取决于该类是被赋予 double 值还是数组作为模板参数: #include "array" #include "type_traits" t
我是一名优秀的程序员,十分优秀!