Django REST Framework JSON API:使用 ResourceRelatedField 时无法解析 URL 的超链接关系
Django REST Framework JSON API: Could not resolve URL for hyperlinked relationship when using ResourceRelatedField
我正在编写一个使用 django + django REST framework + django REST framework JSON API 的 HTTP API。当我尝试执行 PATCH 请求时收到此错误,
Incorrect type. Expected URL string, received OrderedDict
更新关系时。查看问题我明白我需要使用 ResourceRelatedField.
我正在尝试按照此处的文档进行操作 Related fields。下面是我的代码的样子。
urls.py
from django.conf import settings
from django.conf.urls import include, url
from rest_framework import routers
from events import views as e_views
router = routers.DefaultRouter()
router.register(r'events', e_views.EventViewSet)
router.register(r'event-types', e_views.EventTypeViewSet)
urlpatterns = [
url(r'^', include('events.urls')),
url(r'^', include(router.urls)),
]
events/urls.py
from django.conf.urls import url
from .views import EventRelationshipView
urlpatterns = [
url(
regex=r'^events/(?P<event_pk>[^/.]+)/relationships/(?P<related_field>[^/.]+)$',
view=EventRelationshipView.as_view(),
name='event-relationships'
)
]
models.py
from datetime import timedelta
from django.db import models
from django.contrib.gis.db import models as gis_models
class EventType(models.Model):
title = models.CharField(max_length=16)
def __str__(self):
return str(self.title)
class Event(models.Model):
timestamp = models.DateTimeField()
delay = models.DurationField(default=timedelta(0))
event_type = models.ForeignKey(EventType)
name = models.CharField(max_length=16)
location = models.CharField(max_length=200, blank=True)
coordinates = gis_models.PointField(null=True, blank=True)
depth = models.CharField(max_length=64, blank=True)
size = models.IntegerField(null=True, blank=True)
comments = models.TextField(blank=True)
is_virtual = models.BooleanField(default=False)
is_visible = models.BooleanField(default=True)
def __str__(self):
return str(self.name)
serializers.py
from .models import Event, EventType
from rest_framework_json_api import serializers
from rest_framework_json_api.relations import ResourceRelatedField
class EventTypeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = EventType
fields = ('url', 'id', 'title')
class EventSerializer(serializers.HyperlinkedModelSerializer):
included_serializers = {'event_type': EventTypeSerializer}
# THIS PART HERE DOESN'T WORK
event_type = ResourceRelatedField(
queryset=EventType.objects,
related_link_view_name='eventtype-detail',
related_link_url_kwarg='pk',
self_link_view_name='event-relationships'
)
class Meta:
model = Event
fields = ('url', 'id', 'timestamp', 'delay', 'event_type', 'name', 'location',
'coordinates', 'depth', 'size', 'comments', 'is_virtual', 'is_visible')
class JSONAPIMeta:
included_resources = ['event_type']
views.py
# -*- coding: utf-8 -*-
import logging
from rest_framework import viewsets
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework_json_api.parsers import JSONParser
from rest_framework_json_api.renderers import JSONRenderer
from rest_framework_json_api.views import RelationshipView
import django_filters
from .models import Event, EventType
from .serializers import EventSerializer, EventTypeSerializer
class EventFilter(django_filters.rest_framework.FilterSet):
start_timestamp = django_filters.DateTimeFilter(name="timestamp", lookup_expr='gte')
end_timestamp = django_filters.DateTimeFilter(name="timestamp", lookup_expr='lte')
class Meta:
model = Event
fields = ['event_type', 'start_timestamp', 'end_timestamp']
class EventViewSet(viewsets.ModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
parser_classes = (JSONParser,)
renderer_classes = (JSONRenderer,)
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_class = EventFilter
search_fields = ('name', 'location', 'comments')
ordering_fields = '__all__'
class EventTypeViewSet(viewsets.ModelViewSet):
queryset = EventType.objects.all()
serializer_class = EventTypeSerializer
parser_classes = (JSONParser,)
renderer_classes = (JSONRenderer,)
class EventRelationshipView(RelationshipView):
queryset = Event.objects
class EventTypeRelationshipView(RelationshipView):
queryset = EventType.objects
错误
[08/Feb/2017 15:07:44] ERROR [django.request:124] Internal Server Error: /events/6/
Traceback (most recent call last):
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 217, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 215, in _get_response
response = response.render()
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/template/response.py", line 109, in render
self.content = self.rendered_content
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/response.py", line 72, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/renderers.py", line 480, in render
json_api_data = self.build_json_resource_obj(fields, serializer_data, resource_instance, resource_name)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/renderers.py", line 390, in build_json_resource_obj
relationships = cls.extract_relationships(fields, resource, resource_instance)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/renderers.py", line 129, in extract_relationships
field_links = field.get_links(resource_instance)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/relations.py", line 106, in get_links
self_link = self.get_url('self', self.self_link_view_name, self_kwargs, request)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/relations.py", line 90, in get_url
raise ImproperlyConfigured(msg % view_name)
ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "event-relationships".
在 url 参数中将 event_pk
重命名为 pk
解决了问题。
我正在编写一个使用 django + django REST framework + django REST framework JSON API 的 HTTP API。当我尝试执行 PATCH 请求时收到此错误,
Incorrect type. Expected URL string, received OrderedDict
更新关系时。查看问题我明白我需要使用 ResourceRelatedField.
我正在尝试按照此处的文档进行操作 Related fields。下面是我的代码的样子。
urls.py
from django.conf import settings
from django.conf.urls import include, url
from rest_framework import routers
from events import views as e_views
router = routers.DefaultRouter()
router.register(r'events', e_views.EventViewSet)
router.register(r'event-types', e_views.EventTypeViewSet)
urlpatterns = [
url(r'^', include('events.urls')),
url(r'^', include(router.urls)),
]
events/urls.py
from django.conf.urls import url
from .views import EventRelationshipView
urlpatterns = [
url(
regex=r'^events/(?P<event_pk>[^/.]+)/relationships/(?P<related_field>[^/.]+)$',
view=EventRelationshipView.as_view(),
name='event-relationships'
)
]
models.py
from datetime import timedelta
from django.db import models
from django.contrib.gis.db import models as gis_models
class EventType(models.Model):
title = models.CharField(max_length=16)
def __str__(self):
return str(self.title)
class Event(models.Model):
timestamp = models.DateTimeField()
delay = models.DurationField(default=timedelta(0))
event_type = models.ForeignKey(EventType)
name = models.CharField(max_length=16)
location = models.CharField(max_length=200, blank=True)
coordinates = gis_models.PointField(null=True, blank=True)
depth = models.CharField(max_length=64, blank=True)
size = models.IntegerField(null=True, blank=True)
comments = models.TextField(blank=True)
is_virtual = models.BooleanField(default=False)
is_visible = models.BooleanField(default=True)
def __str__(self):
return str(self.name)
serializers.py
from .models import Event, EventType
from rest_framework_json_api import serializers
from rest_framework_json_api.relations import ResourceRelatedField
class EventTypeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = EventType
fields = ('url', 'id', 'title')
class EventSerializer(serializers.HyperlinkedModelSerializer):
included_serializers = {'event_type': EventTypeSerializer}
# THIS PART HERE DOESN'T WORK
event_type = ResourceRelatedField(
queryset=EventType.objects,
related_link_view_name='eventtype-detail',
related_link_url_kwarg='pk',
self_link_view_name='event-relationships'
)
class Meta:
model = Event
fields = ('url', 'id', 'timestamp', 'delay', 'event_type', 'name', 'location',
'coordinates', 'depth', 'size', 'comments', 'is_virtual', 'is_visible')
class JSONAPIMeta:
included_resources = ['event_type']
views.py
# -*- coding: utf-8 -*-
import logging
from rest_framework import viewsets
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework_json_api.parsers import JSONParser
from rest_framework_json_api.renderers import JSONRenderer
from rest_framework_json_api.views import RelationshipView
import django_filters
from .models import Event, EventType
from .serializers import EventSerializer, EventTypeSerializer
class EventFilter(django_filters.rest_framework.FilterSet):
start_timestamp = django_filters.DateTimeFilter(name="timestamp", lookup_expr='gte')
end_timestamp = django_filters.DateTimeFilter(name="timestamp", lookup_expr='lte')
class Meta:
model = Event
fields = ['event_type', 'start_timestamp', 'end_timestamp']
class EventViewSet(viewsets.ModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
parser_classes = (JSONParser,)
renderer_classes = (JSONRenderer,)
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_class = EventFilter
search_fields = ('name', 'location', 'comments')
ordering_fields = '__all__'
class EventTypeViewSet(viewsets.ModelViewSet):
queryset = EventType.objects.all()
serializer_class = EventTypeSerializer
parser_classes = (JSONParser,)
renderer_classes = (JSONRenderer,)
class EventRelationshipView(RelationshipView):
queryset = Event.objects
class EventTypeRelationshipView(RelationshipView):
queryset = EventType.objects
错误
[08/Feb/2017 15:07:44] ERROR [django.request:124] Internal Server Error: /events/6/
Traceback (most recent call last):
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 217, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 215, in _get_response
response = response.render()
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/template/response.py", line 109, in render
self.content = self.rendered_content
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/response.py", line 72, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/renderers.py", line 480, in render
json_api_data = self.build_json_resource_obj(fields, serializer_data, resource_instance, resource_name)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/renderers.py", line 390, in build_json_resource_obj
relationships = cls.extract_relationships(fields, resource, resource_instance)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/renderers.py", line 129, in extract_relationships
field_links = field.get_links(resource_instance)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/relations.py", line 106, in get_links
self_link = self.get_url('self', self.self_link_view_name, self_kwargs, request)
File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework_json_api/relations.py", line 90, in get_url
raise ImproperlyConfigured(msg % view_name)
ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "event-relationships".
在 url 参数中将 event_pk
重命名为 pk
解决了问题。