Невозможно создать NestedHyperlinkedIdentityField на глубине 2 уровня от источника, который является обратной связью родителя с использованием drf-nested-router - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь отобразить URL-адрес вложенного маршрута глубиной 2 или более, используя модуль drf-nested-routes и Django Rest Framework.У меня нет проблем, когда он всего на один уровень (т. Е. Получается маршрут с parent_lookup_kwargs), но я получаю следующую ошибку, когда пытаюсь пойти глубже:

AttributeError в / en / api/v1.0/Sensors(1)/Datastreams(1)/Things У объекта «RelatedManager» нет атрибута «Сенсоры»

Вот некоторые из соответствующих сериализаторов:

class ThingSerializer(SelectSerializerMixin,
                      ExpanderSerializerMixin,
                      serializers.ModelSerializer):
    class Meta:
        model = Thing
        fields = ('@iot.id',
                  '@iot.selfLink',
                  'Locations@iot.navigationLink',

    ...

ThingSerializer._declared_fields["Datastreams@iot.navigationLink"] = \
    NestedHyperlinkedIdentityField(
        view_name='sensor-location-list',
        parent_lookup_kwargs={'Sensors_pk':'Datastreams__Sensors__pk',
                              'nested_2_pk': 'Datastreams__pk'},
        lookup_url_kwarg='nested_3_pk'
        )

Я пытаюсь показать URL соответствующего поля.Вот доступные URL-маршруты:

en/ api/v1.0/ ^Sensors\((?P<Sensors_pk>[^/.]+)\)/Datastreams\((?P<nested_2_pk>[^/.]+)\)/Things\((?P<nested_3_pk>[^/.]+)\)/Locations$ [name='sensor-location-list']

en/ api/v1.0/ ^Sensors\((?P<Sensors_pk>[^/.]+)\)/Datastreams\((?P<nested_2_pk>[^/.]+)\)/Things\((?P<nested_3_pk>[^/.]+)\)/HistoricalLocations$ [name='sensor-historicallocation-list']

Маршруты зарегистрированы, и я не могу получить доступ к вложенным ресурсам без проблем.Это только когда я пытаюсь создать ресурс NestedHyperlinkedIdentityField, который терпит неудачу.

ПРИМЕЧАНИЕ, я могу заставить это работать, если я использую Many=True в NestedHyperlinkedIdentityField и изменю поле source так, чтобы оно было не более 1 родительского уровня:

NestedHyperlinkedIdentityField(
                    view_name='sensor-location-list',
                    many=True,
                    source='Datastreams',
                    parent_lookup_kwargs={'Sensors_pk': 'Sensors__pk',
                                          'nested_2_pk': 'pk'},
                    lookup_url_kwarg='nested_3_pk'
                    )

Но, это создает объект ManyRelatedField, поэтому сериализованный вывод:

"Locations@iot.navigationLink": [
                "http://localhost:8000/en/api/v1.0/Sensors(1)/Datastreams(1)/Things(1)/Locations"
            ],

Требуемый вывод:

"Locations@iot.navigationLink": "http://localhost:8000/en/api/v1.0/Sensors(1)/Datastreams(1)/Things(1)/Locations",

Любая помощь будет высоко ценится ^^.

edit: Похоже, что он не получит URL, если модель, используемая в сериализаторе, является обратной связью родителя.Вы можете увидеть это в части models.py:

class DataStream(models.Model):
    ....
    Things = models.ForeignKey(Thing,
                               on_delete=models.SET_NULL,
                               null=True,
                               related_name="Datastreams"
    Sensors = models.ForeignKey(Sensor,
                                on_delete=models.SET_NULL,
                                ...
...