【问题标题】:Add a HyperLink in django-rest-framework to a ModelViewSet将 django-rest-framework 中的超链接添加到 ModelViewSet
【发布时间】:2015-11-08 02:49:30
【问题描述】:

在 Django Rest Framework 中是否可以在链接到 详细视图 的 ModelViewSet 列表视图 中每条记录的 id 字段上添加 HyperLink为了那个记录?

documentation 说要添加一个 view_name 参数,但这是否可以在 ModelViewSet 下执行,因为视图实际上没有名称?

【问题讨论】:

    标签: python django rest django-rest-framework


    【解决方案1】:

    xleon 回答的一点更新:

    使用 Python 3 和新的 Django,查看所有 urlpatterns 的函数你应该使用这样的东西:

    def print_url_pattern_names(patterns):
        """Print a list of urlpattern and their names"""
        for pat in patterns:
            if pat.__class__.__name__ == 'URLResolver':      # load patterns from this URLResolver
                print_url_pattern_names(pat.url_patterns)
            elif pat.__class__.__name__ == 'URLPattern':     # load name from this URLPattern
                if pat.name is not None:
                    print('[API-URL] {:>50} -> {}'.format(pat.name, pat.pattern))
    

    我花了一些时间解决它,所以也许它会对某人有所帮助。

    我是如何使用它的:运行“python manage.py shell”,然后

    import urls
    

    然后复制这个函数并像这样运行它:

    print_url_pattern_names(urls.urlpatterns)
    

    【讨论】:

      【解决方案2】:

      第一件事是所有 ModelViewSet url 都有名称,即使您没有明确设置这些名称。

      您可以在文档中了解如何在路由器中创建默认 url:http://www.django-rest-framework.org/api-guide/routers/(请参阅“SimpleRouter”url 名称表)

      要查看应用程序中所有可用的实际 url 名称,请尝试使用此实用程序:

      def print_url_pattern_names(patterns):
          """Print a list of urlpattern and their names"""
          for pat in patterns:
              if pat.__class__.__name__ == 'RegexURLResolver':            # load patterns from this RegexURLResolver
                  print_url_pattern_names(pat.url_patterns)
              elif pat.__class__.__name__ == 'RegexURLPattern':           # load name from this RegexURLPattern
                  if pat.name is not None:
                      print '[API-URL] {} \t\t\t-> {}'.format(pat.name, pat.regex.pattern)
      

      然后,在你的 urls.py 中:

      urlpatterns = [
          url(r'^', include(router.urls)),
      ]
      
      if settings.DEBUG:
          print_url_pattern_names(urlpatterns)
      

      如果您希望 url 与您的 ModelViewSet 的名称不同(如我的情况),您可以使用“base_name”在路由器上设置它:

      router.register('contents', media_views.MediaViewSet, base_name='contents')
      

      接下来您需要扩展 HyperlinkedModelSerializer:

      from rest_framework import serializers
      # in this sample my object is of type "Media"
      class MediaSerializer(serializers.HyperlinkedModelSerializer):
          #blablabla
      

      您将准备好一个序列化程序来显示指向您的详细视图的超链接,但是还需要一个必要的步骤才能使其正常工作。这就是“view_name”的来源:

      from rest_framework import serializers
      class MediaSerializer(serializers.HyperlinkedModelSerializer):
          class Meta:
              model = Media
              fields = ('url', ...[other fields you want to serialize])
              extra_kwargs = {
                  'url': {'view_name': 'contents-detail'}
              }
      
      1. “url”字段是显示链接的必填字段。
      2. 使用 'extra_kwargs' > view_name 你告诉框架你的细节视图的名字是'content-detail'。
      3. 'content-detail' 只是我的视图名称。你 需要找出你的(从上面的 url names 实用程序)

      这是来自示例的 http 响应(请参阅 url 字段):

      【讨论】:

      • 在这里您将'contents-detail' 设置为网址名称。需要在urls.py中声明这个url吗?
      • 没有。正如我所提到的,路由器/模型视图集将为您创建 url:django-rest-framework.org/api-guide/routers。但在我的特殊情况下,鉴于我希望 url 以“内容”而不是“媒体”开头,我将其设置在 urls.py 上(编辑了帖子)
      • 我删除了 view_name 的 extra_kwargs,因为在 HyperlinkedModelSerializer 中不需要它并且它有效。此外,这个答案帮助我让它工作:stackoverflow.com/a/20553926/1913888。我仍然为您的回答+1。谢谢。
      猜你喜欢
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-22
      • 1970-01-01
      相关资源
      最近更新 更多