问题
New to DRF and everything works as long as I don't include 'url' in fields. Here's what I've got:
Serializer:
class TaskSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Task
fields = ('pk', 'short_desc', 'scheduled_date')
View Set:
class TaskViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Task.objects.all().order_by('scheduled_date')
serializer_class = TaskSerializer
URLs:
router = routers.DefaultRouter()
router.register(r'tasks', views.TaskViewSet)
urlpatterns = [
[... bunch of non-REST URLs]
# REST API
url(r'^', include(router.urls)),
At runtime, printing router.urls gives me:
<RegexURLPattern api-root ^$>
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
<RegexURLPattern task-list ^tasks/$>
<RegexURLPattern task-list ^tasks\.(?P<format>[a-z0-9]+)/?$>
<RegexURLPattern task-detail ^tasks/(?P<pk>[^/.]+)/$>
<RegexURLPattern task-detail ^tasks/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>
Both [...]/tasks/
and [...]/tasks/123/
work if I type them into my browser, which leads me to believe that task-list and task-detail views do, in fact exist.
Now I introduce a problem by adding 'url' to the serializer:
class TaskSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Task
fields = ('url', 'pk', 'short_desc', 'scheduled_date')
After adding 'url' to fields, I get the following error:
Could not resolve URL for hyperlinked relationship using view name "task-detail". You may have failed to include the related model in your API, or incorrectly configured the
lookup_field
attribute on this field.
The DRF docs say:
There needs to be a way of determining which views should be used for hyperlinking to model instances. By default hyperlinks are expected to correspond to a view name that matches the style '{model_name}-detail', and looks up the instance by a pk keyword argument.
Since I've verified that task-detail exists and that the corresponding URL [...]/tasks/123/
works, I can't for the life of me figure out why DRF can't form the URL. Any ideas?
回答1:
Inspired by clues revealed by Kunkka's answer, I have a solution that looks like this:
class TaskSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="task:task-detail")
class Meta:
model = Task
fields = ('url', 'pk', 'short_desc', 'scheduled_date')
I.e. I've added an url = [...]
line to the serializer I originally posted in my question. This solves the lookup problem which was presumably caused by DRF not knowing that 'task-detail' is actually in the 'task' namespace.
Any better solutions?
回答2:
Can you try this?
class TaskSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField()
class Meta:
model = Task
fields = ('pk','url', 'short_desc', 'scheduled_date')
def get_url(self,obj):
request = self.context['request']
return = {'self':reverse('task-detail',kwargs={'pk':obj.pk},request=request)}
来源:https://stackoverflow.com/questions/33201520/why-cant-django-rest-frameworks-hyperlinkedmodelserializer-form-url