我正在尝试使用超链接模型。我已经花了很长时间才能使端点/repositories/<owner>/<name>
正常工作。现在我遇到的问题是Session
应该使用相同的URL存储Repository
的外键。我收到以下错误。
无法使用视图名称“repository-detail”解析超链接关系的URL。您可能未能在API中包含相关模型,或者在此字段上错误地配置了
lookup_field
属性。
我定义了以下内容。
models.py
class Repository(models.Model):
owner = models.CharField(max_length=255)
name = models.CharField(max_length=255)
platform = models.CharField(max_length=255)
class Meta:
db_table = 'repository'
class PullRequest(models.Model):
repository = models.ForeignKey(Repository, on_delete=models.CASCADE, null=True)
pull_request_number = models.PositiveIntegerField()
class Meta:
db_table = 'pull_request'
serializers.py
class MultiKeyHyperlinkedIdentityField(serializers.HyperlinkedIdentityField):
identity_args = {}
def get_url(self, obj, view_name, request, format):
if obj.pk is None:
return None
kwargs = dict((url_kw, getattr(obj, prop)) for url_kw, prop in self.identity_args.items())
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
class RepositoryHyperlinkedIdentityField(MultiKeyHyperlinkedIdentityField):
identity_args = {
'owner': 'owner',
'name': 'name'
}
class RepositorySerializer(serializers.HyperlinkedModelSerializer):
url = RepositoryHyperlinkedIdentityField(view_name='repository-detail')
class Meta:
model = Repository
fields = ('url', 'owner', 'name', 'platform')
class PullRequestSerializer(serializers.HyperlinkedModelSerializer):
repository = serializers.HyperlinkedIdentityField(view_name='repository-detail')
class Meta:
model = PullRequest
fields = ('url', 'repository', 'pull_request_number')
views.py
class MultipleFieldLookupMixin(object):
"""
Apply this mixin to any view or viewset to get multiple field filtering
based on a `lookup_fields` attribute, instead of the default single field filtering.
"""
def get_object(self):
queryset = self.get_queryset() # Get the base queryset
queryset = self.filter_queryset(queryset) # Apply any filter backends
filter = {}
for field in self.lookup_fields:
filter[field] = self.kwargs[field]
return get_object_or_404(queryset, **filter) # Lookup the object
class MultipleFieldRetrieveAPIView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
pass
class RepositoryList(generics.ListCreateAPIView):
queryset = Repository.objects.all()
serializer_class = RepositorySerializer
class RepositoryDetail(MultipleFieldRetrieveAPIView):
queryset = Repository.objects.all()
serializer_class = RepositorySerializer
lookup_fields = ('owner', 'name')
class PullRequestList(generics.ListCreateAPIView):
queryset = PullRequest.objects.all()
serializer_class = PullRequestSerializer
class PullRequestDetail(generics.RetrieveAPIView):
queryset = PullRequest.objects.all()
serializer_class = PullRequestSerializer
urls.py
urlpatterns = [
url(r'^$', views.api_root),
url(r'^repositories/$', views.RepositoryList.as_view(), name='repository-list'),
url(r'^repositories/(?P<owner>.+)/(?P<name>.+)/$', views.RepositoryDetail.as_view(), name='repository-detail'),
url(r'^pullrequests/$', views.PullRequestList.as_view(), name='pullrequest-list'),
url(r'^pullrequests/(?P<pk>[0-9]+)/$', views.PullRequestDetail.as_view(), name='pullrequest-detail'),
]
希望有人可以帮助我。提前谢谢!