master
分支中。代码
from rest_framework import serializers
from incidents.models import Incident
class NodeDataField(serializers.RelatedField):
def to_representation(self, node):
return {
"id": node.id,
"name": node.name,
"ipaddress": node.ipv4
}
def to_internal_value(self, id):
pass
这在 /api/v1/incidents/ 给出 TypeError
不可散列的类型:'dict'
unhashable type: 'dict'
5 <label class="col-sm-2 control-label {% if style.hide_label %}sr-only{% endif %}">
6 {{ field.label }}
7 </label>
8 {% endif %}
9
10 <div class="col-sm-10">
11 <select class="form-control" name="{{ field.name }}">
12 {% if field.allow_null or field.allow_blank %}
13 <option value="" {% if not field.value %}selected{% endif %}>--------</option>
14 {% endif %}
15
{% for select in field.iter_options %}
16 {% if select.start_option_group %}
17 <optgroup label="{{ select.label }}">
18 {% elif select.end_option_group %}
19 </optgroup>
20 {% else %}
21 <option value="{{ select.value }}" {% if select.value|as_string == field.value|as_string %}selected{% endif %} {% if select.disabled %}disabled{% endif %}>{{ select.display_text }}</option>
22 {% endif %}
23 {% endfor %}
24 </select>
堆栈跟踪
/opt/grofers/firealarm-api/api/firealarm_api/lib/python3.4/_collections_abc.py in update
self[key] = value
...
▶ Local vars
/opt/grofers/firealarm-api/api/firealarm_api/lib/python3.4/collections/__init__.py in __setitem__
self.__update(*args, **kwds)
def __setitem__(self, key, value,
dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link at the end of the linked list,
# and the inherited dictionary is updated with the new key/value pair.
if key not in self:
...
self.__map[key] = link = Link()
root = self.__root
last = root.prev
link.prev, link.next, link.key = last, root, key
last.next = link
root.prev = proxy(link)
▼ Local vars
Variable Value
self
OrderedDict()
dict_setitem
<slot wrapper '__setitem__' of 'dict' objects>
value
'Node object'
proxy
<built-in function proxy>
Link
<class 'collections._Link'>
key
{'id': 1, 'ipaddress': '172.31.84.130', 'name': 'abc123.con'}
它应该显示 rest-framework 的可浏览 API 视图页面
在 /api/v1/incidents/ 出现 TypeError 失败
不可散列的类型:'dict'
嗨@manjitkumar - RelatedField
通常将相关对象表示为单个值(例如,slug、主键、url 等...)。 如果要提供嵌套对象表示,则应使用嵌套序列化程序。
我试图以某种方式避免覆盖序列化程序的create
和update
方法。 为此,我编写了一个小类来帮助我做到这一点,但由于某种原因,我有一个与此相关的错误。
class PrimaryKeyField(serializers.RelatedField):
def __init__(self, serializer, **kwargs):
self.serializer = serializer(**kwargs)
if "queryset" not in kwargs:
kwargs["queryset"] = self.serializer.Meta.model.objects.all()
self.pk_field = serializers.PrimaryKeyRelatedField(**kwargs)
super().__init__(**kwargs)
def to_representation(self, instance):
return self.serializer.to_representation(instance)
def to_internal_value(self, data):
try:
return self.pk_field.to_internal_value(data["id"])
except TypeError:
return data
问题是我在to_representation
方法中得到了unhashable type: 'collections.OrderedDict'
。 我不明白为什么。
建议一些升级?
我遇到这个错误是因为我在 to_representation() 上实现了一个dict
类型的返回,所以当它试图在页面上生成表单时,它遇到了一个错误。
也许很清楚而且我很傻,但是有没有办法用现有的类来实现下面的内容?
class AnyRelatedField(serializers.RelatedField):
def __init__(self, query_fields=tuple(), **kwargs):
if not query_fields:
raise NotImplementedError("AnyRelatedField requires a query field names to be provided as a tuple")
self.query_fields = query_fields
self.query_objects = Q()
super().__init__(**kwargs)
def to_internal_value(self, data):
for field in self.query_fields:
if field in ['pk', 'id'] and not isinstance(data, int):
continue
self.query_objects |= Q(**{field: data})
try:
self.instance = self.queryset.get(self.query_objects)
return self.instance
except self.queryset.model.DoesNotExist:
raise serializers.ValidationError(
detail="{} object does not exist with {}: {}".format(
self.queryset.model.__name__, ', '.join(self.query_fields), data
),
code=self.field_name
)
def to_representation(self, val):
return val
最有用的评论
我试图以某种方式避免覆盖序列化程序的
create
和update
方法。 为此,我编写了一个小类来帮助我做到这一点,但由于某种原因,我有一个与此相关的错误。问题是我在
to_representation
方法中得到了unhashable type: 'collections.OrderedDict'
。 我不明白为什么。