master
du framework Django REST.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
Cela donne TypeError à /api/v1/incidents/
type non illisible : '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>
Trace de la pile
/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'}
Il devrait afficher la page d'affichage de l'API navigable de rest-framework
Échec avec TypeError dans /api/v1/incidents/
type non illisible : 'dict'
Salut @manjitkumar - RelatedField
s représentent généralement un objet connexe comme une valeur unique (par exemple, un slug, une clé primaire, une URL, etc...). Si vous souhaitez fournir une représentation d'objet imbriquée, vous devez utiliser un sérialiseur imbriqué .
J'essaie d'éviter d'écraser les méthodes create
et update
d'un sérialiseur là où je le peux. Pour cela, j'ai écrit une petite classe pour m'aider à le faire, mais pour une raison quelconque, j'ai une erreur liée à celle-ci.
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
Le fait est que j'obtiens unhashable type: 'collections.OrderedDict'
dans la méthode to_representation
. Et je ne comprends pas pourquoi.
Suggérer des améliorations ?
Je suis tombé sur cette erreur parce que j'implémentais un retour sur to_representation() qui était de type dict
donc quand il a essayé de générer le formulaire sur la page, il s'est retrouvé avec une erreur.
C'est peut-être clair et je suis idiot, mais y a-t-il un moyen d'implémenter ce qui suit avec les classes existantes ?
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
Commentaire le plus utile
J'essaie d'éviter d'écraser les méthodes
create
etupdate
d'un sérialiseur là où je le peux. Pour cela, j'ai écrit une petite classe pour m'aider à le faire, mais pour une raison quelconque, j'ai une erreur liée à celle-ci.Le fait est que j'obtiens
unhashable type: 'collections.OrderedDict'
dans la méthodeto_representation
. Et je ne comprends pas pourquoi.