master
Zweig des Django REST-Frameworks besteht.Code
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
Dies gibt TypeError unter /api/v1/incidents/
Unhashable-Typ: '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>
Stapelverfolgung
/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'}
Es sollte die durchsuchbare API-Ansichtsseite von rest-framework anzeigen
Fehler mit TypeError unter /api/v1/incidents/
Unhashable-Typ: 'dict'
Hallo @manjitkumar - RelatedField
s repräsentieren im Allgemeinen ein verwandtes Objekt als einen einzelnen Wert (zB ein Slug, Primärschlüssel, URL, etc...). Wenn Sie eine verschachtelte Objektdarstellung bereitstellen möchten, sollten Sie einen verschachtelten Serializer verwenden .
Ich versuche irgendwie zu vermeiden, die Methoden create
und update
eines Serializers zu überschreiben, wo ich kann. Dafür habe ich eine kleine Klasse geschrieben, die mir dabei hilft, aber aus irgendeinem Grund habe ich einen Fehler in diesem Zusammenhang.
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
Die Sache ist, dass ich unhashable type: 'collections.OrderedDict'
in der Methode to_representation
erhalte. Und ich verstehe nicht warum.
Einige Upgrades vorschlagen?
Ich bin auf diesen Fehler gestoßen, weil ich eine Rückgabe von to_representation() implementiert habe, die vom Typ dict
Beim Versuch, das Formular auf der Seite zu generieren, wurde ein Fehler festgestellt.
Vielleicht ist es klar und ich bin albern, aber gibt es eine Möglichkeit, das Folgende mit vorhandenen Klassen zu implementieren?
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
Hilfreichster Kommentar
Ich versuche irgendwie zu vermeiden, die Methoden
create
undupdate
eines Serializers zu überschreiben, wo ich kann. Dafür habe ich eine kleine Klasse geschrieben, die mir dabei hilft, aber aus irgendeinem Grund habe ich einen Fehler in diesem Zusammenhang.Die Sache ist, dass ich
unhashable type: 'collections.OrderedDict'
in der Methodeto_representation
erhalte. Und ich verstehe nicht warum.