无法使超链接关系正常工作

时间:2016-05-17 17:55:24

标签: python django-rest-framework

我正在尝试使用超链接模型。我已经花了很长时间才能使端点/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'),
]

希望有人可以帮助我。提前谢谢!

0 个答案:

没有答案