master
dari kerangka kerja Django REST.Kode
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
Ini memberikan TypeError di /api/v1/incidents/
jenis yang tidak dapat dihash: '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>
Jejak tumpukan
/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'}
Itu akan menampilkan halaman tampilan API yang dapat dijelajahi rest-framework
Gagal dengan TypeError di /api/v1/incidents/
jenis yang tidak dapat dihash: 'dict'
Hai @manjitkumar - RelatedField
s umumnya mewakili objek terkait sebagai nilai tunggal (misalnya, siput, kunci utama, url, dll...). Jika Anda ingin memberikan representasi objek bersarang, maka Anda harus menggunakan serializer bersarang .
Saya mencoba untuk menghindari menimpa metode create
dan update
dari serializer di mana saya bisa. Untuk ini, saya telah menulis kelas kecil untuk membantu saya melakukan ini, tetapi untuk beberapa alasan, saya memiliki kesalahan terkait dengan yang satu ini.
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
Masalahnya adalah saya mendapatkan unhashable type: 'collections.OrderedDict'
dalam metode to_representation
. Dan saya tidak mengerti mengapa.
Sarankan beberapa peningkatan?
Saya menemukan kesalahan ini karena saya menerapkan pengembalian to_representation() yang bertipe dict
jadi ketika mencoba membuat formulir pada halaman itu terjebak dengan kesalahan.
Mungkin sudah jelas dan saya konyol, tetapi apakah ada cara untuk mengimplementasikan di bawah ini dengan kelas yang ada?
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
Komentar yang paling membantu
Saya mencoba untuk menghindari menimpa metode
create
danupdate
dari serializer di mana saya bisa. Untuk ini, saya telah menulis kelas kecil untuk membantu saya melakukan ini, tetapi untuk beberapa alasan, saya memiliki kesalahan terkait dengan yang satu ini.Masalahnya adalah saya mendapatkan
unhashable type: 'collections.OrderedDict'
dalam metodeto_representation
. Dan saya tidak mengerti mengapa.