I've extensively researched this fairly common issue, but none of the fixes worked for me. I'm building a Django project in REST framework and want to use hyperlinked relations. The User can have many Cars and Routes, which are independent. A Route is a collection of Positions.
These are my serializers:
class CarSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.Field(source='user.username')
class Meta:
model = Car
fields = ('url', 'make', 'year', 'car_model', 'user')
class PositionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Position
fields = ('url', 'drive_route', 'timestamp', 'latitude', 'longitude', 'altitude','speed','heading', 'accuracy', 'altitude_accuracy')
class DrivingRouteSerializer(serializers.HyperlinkedModelSerializer):
position = serializers.HyperlinkedRelatedField(view_name='position', many=True)
user = serializers.Field(source='user.username')
class Meta:
model = DrivingRoute
fields = ('url', 'id', 'route', 'position', 'user')
class UserSerializer(serializers.HyperlinkedModelSerializer):
routes = serializers.HyperlinkedRelatedField(view_name='routes-detail', many=True)
car = serializers.HyperlinkedRelatedField(view_name='car-detail', many=True)
class Meta:
model = User
fields = ('url', 'username', 'routes', 'car')
And here are the views:
class CarViewSet(viewsets.ModelViewSet):
queryset = Car.objects.all()
serializer_class = CarSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def pre_save(self, obj):
obj.user = self.request.user
class DrivingRouteViewSet(viewsets.ModelViewSet):
queryset = DrivingRoute.objects.all()
serializer_class = DrivingRouteSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def pre_save(self, obj):
obj.user = self.request.user
class PositionViewSet(viewsets.ModelViewSet):
queryset = Position.objects.all()
serializer_class = PositionSerializer
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
And, for what it's worth, the URLs. I am using the Default Router, just as in the Django REST Framwork tutorial.
router = DefaultRouter()
router.register(r'car', views.CarViewSet)
router.register(r'routes', views.DrivingRouteViewSet)
router.register(r'position', views.PositionViewSet)
router.register(r'users', views.UserViewSet)
Overall, this is almost exactly the same as in the tutorial. Loading the 'routes', 'car', and 'position' URLS works fine, but the 'users' URL throws the error "Could not resolve URL for hyperlinked relationship using view name 'routes-detail'."
You have the following views:
If we take for example the following route:
It means that it is accessible under http://yourapi.com/car/ for car-list and under http://yourapi.com/car/1/ for car-detail (where 1 is the id).
The view names get built out of the class name minus suffix ViewSet plus list or detail.
Change your code according to these rules and please try again.
Cheers!
The
view_name
should typically be[route]-detail
for routers, where[route]
is the name of the model you registered theViewSet
under.In your case, the
view_name
should beposition-detail
, not justposition
. You are also usingroutes-detail
instead ofdrivingroutes-detail
, which is using the long name because your model isDrivingRoute
and notRoute
. You can override this by setting abase_name
(third parameter) when usingregister
on the router.