Django-rest-framework: рдЯрд╛рдЗрдк рдПрд░рд░ рдЕрдирд╣реИрд╢рдмрд▓ рдЯрд╛рдЗрдк: рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд░реНрд╕ рдореЗрдВ рд░рд┐рд▓реЗрдЯреЗрдбрдлрд┐рд▓реНрдб рдХреЗ рд╕рд╛рде 'рддрд╛рдирд╛рд╢рд╛рд╣'

рдХреЛ рдирд┐рд░реНрдорд┐рдд 28 рдЕрдкреНрд░реИрд▓ 2017  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: encode/django-rest-framework

рдЬрд╛рдВрдЪ рд╕реВрдЪреА

  • [x] рдореИрдВрдиреЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдорд╕реНрдпрд╛ Django REST рдврд╛рдВрдЪреЗ рдХреА master рд╢рд╛рдЦрд╛ рдХреЗ рд╡рд┐рд░реБрджреНрдз рдореМрдЬреВрдж рд╣реИред
  • [x] рдореИрдВрдиреЗ рдЦреБрд▓реЗ рдФрд░ рдмрдВрдж рджреЛрдиреЛрдВ рдЯрд┐рдХрдЯреЛрдВ рдореЗрдВ рд╕рдорд╛рди рдореБрджреНрджреЛрдВ рдХреА рдЦреЛрдЬ рдХреА рд╣реИ рдФрд░ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИред
  • [x] рдпрд╣ рдЙрдкрдпреЛрдЧ рдХрд╛ рдкреНрд░рд╢реНрди рдирд╣реАрдВ рд╣реИред (рдЙрдиреНрд╣реЗрдВ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЪрд░реНрдЪрд╛ рд╕рдореВрд╣ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред)
  • [x] рдЗрд╕реЗ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред (рдЬрд╣рд╛рдВ рд╕рдВрднрд╡ рд╣реЛ, рд╣рдо рддреГрддреАрдп рдкрдХреНрд╖ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрддреЗ рд╣реИрдВред)
  • [x] рдореИрдВрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕рд░рд▓рддрдо рд╕рдВрднрд╡ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдо рдХрд░ рджрд┐рдпрд╛ рд╣реИред
  • [ ] рдореИрдВрдиреЗ рдПрдХ рдЕрд╕рдлрд▓ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рд░реВрдк рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рд╣реИред (рдпрджрд┐ рдЖрдк рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рд╣реИрдВ рддреЛ рднреА рд╣рдо рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред)

рдХреЛрдб

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/рдШрдЯрдирд╛рдУрдВ рдкрд░ TypeError рджреЗрддрд╛ рд╣реИред
рдЕрдкреНрд░рд╛рдкреНрдп рдкреНрд░рдХрд╛рд░: 'рддрд╛рдирд╛рд╢рд╛рд╣'

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'}

рдкреНрд░рдЬрдирди рдХреЗ рдЪрд░рдг

  1. рдЙрд╕ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ GET рдХреЙрд▓ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рдЗрд╕ рд╕рдВрдмрдВрдзрд┐рдд рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝рд░ рдлрд╝реАрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рдФрд░ /?format=api рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдмрдХрд┐ /?format=json рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ рд╣реИред

    рдЕрдкреЗрдХреНрд╖рд┐рддреН рд╡реНрдпрд╡рд╣рд╛рд░

рдЗрд╕реЗ рд░реЗрд╕реНрдЯ-рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдмреНрд░рд╛рдЙрдЬрд╝ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдПрдкреАрдЖрдИ рд╡реНрдпреВ рдкреЗрдЬ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░

/api/v1/рдШрдЯрдирд╛рдУрдВ рдкрд░ TypeError рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд╣реЛрдирд╛
рдЕрдкреНрд░рд╛рдкреНрдп рдкреНрд░рдХрд╛рд░: 'рддрд╛рдирд╛рд╢рд╛рд╣'

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдПрдХ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдХреЗ 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

рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдореБрдЭреЗ unhashable type: 'collections.OrderedDict' to_representation рдкрджреНрдзрддрд┐ рдореЗрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИред рдФрд░ рдореБрдЭреЗ рд╕рдордЭ рдирд╣реАрдВ рдЖрддрд╛ рдХреНрдпреЛрдВред

рд╕рднреА 3 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рд╣рд╛рдп @manjitkumar - RelatedField s рдЖрдо рддреМрд░ рдкрд░ рдПрдХ рд╕рдВрдмрдВрдзрд┐рдд рд╡рд╕реНрддреБ рдХреЛ рдПрдХ рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕реНрд▓рдЧ, рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА, рдпреВрдЖрд░рдПрд▓, рдЖрджрд┐ ...)ред рдпрджрд┐ рдЖрдк рдиреЗрд╕реНрдЯреЗрдб рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдиреЗрд╕реНрдЯреЗрдб рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореИрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдПрдХ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдХреЗ 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

рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдореБрдЭреЗ unhashable type: 'collections.OrderedDict' to_representation рдкрджреНрдзрддрд┐ рдореЗрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИред рдФрд░ рдореБрдЭреЗ рд╕рдордЭ рдирд╣реАрдВ рдЖрддрд╛ рдХреНрдпреЛрдВред

рдХреБрдЫ рдЙрдиреНрдирдпрди рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрдВ?
рдореБрдЭреЗ рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ 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
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

MadWombat picture MadWombat  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

snbuback picture snbuback  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rjdp picture rjdp  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

macropin picture macropin  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Lucidiot picture Lucidiot  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ