【问题标题】:Django rest framework not indexing a custom CBV in Api RootDjango rest 框架未在 Api Root 中索引自定义 CBV
【发布时间】:2015-12-17 01:24:38
【问题描述】:

在 Django-rest-framework 中,我有一个简单的 CBV

class LocationList(APIView):
    """
    List all locations (id and name)
    """
    def get(self, request, format=None):
        # Make connection to SQL server db
        dbargs = dict(
            DRIVER='{FreeTDS}',
            SERVER=django_settings.DB_HOST,
            PORT=django_settings.DB_PORT,
            DATABASE=django_settings.DB_NAME,
            UID=django_settings.DB_USER,
            PWD=django_settings.DB_PWD,
        )

        cnxn = pyodbc.connect(**dbargs)    
        # Query db
        curs = cnxn.cursor()
        select_locations_cmd = 'SELECT list_id, cast(list_name as text) FROM location_lists;'
        curs = curs.execute(select_locations_cmd)

        # Serialize
        sdata = [dict(list_id=lid, list_name=lname) for lid, lname in curs.fetchall()]

        # Close cnxn
        cnxn.close()

        return Response(sdata)

正如您所见,它所做的只是查询外部数据库,手动序列化结果并将其返回到 django-rest-framework Response 对象中。

在我的urls.py 我有

router = routers.DefaultRouter()
router.register(r'someothermodel', SomeOtherModelViewSet)


urlpatterns = [url(r'^', include(router.urls)),
               url(r'^locationlists/$', LocationList.as_view(), name="weather-location-lists"),

               ]

这工作正常,但我担心的是,当我访问根 API url 时,它只显示someothermodel 的端点,它是通过路由器注册并使用标准 ViewSet。它根本没有列出 locationlists 端点。 我可以在浏览器中访问 /locationlists 端点(或者向它发出 GET 请求而不会出现问题),但它没有被编入索引

如何在根目录索引它?所以它出现在旁边

Api Root
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "someothertask": "http://127.0.0.1:8000/someothertask/",
}

【问题讨论】:

    标签: django-rest-framework


    【解决方案1】:

    您所指的页面由路由器供电,在您的情况下,LocationList 未通过路由器注册。因此它不会出现在端点列表中。

    正如@Linovia 所指出的,路由器只处理视图集。但是,只需进行一些更改,这很容易实现:

    # views.py
    from rest_framework.viewsets import ViewSet
    
    class LocationList(ViewSet):
    
        def list(self, request, format=None):  # get -> list
            ...
    
    # urls.py
    router = routers.DefaultRouter()
    router.register(r'someothermodel', SomeOtherModelViewSet)
    router.register(r'locationlists', LocationList, base_name='weather-location')
    
    urlpatterns = [
        url(r'^', include(router.urls)),
    ]
    

    您现在应该看到:

    {
        "someothertask": "http://127.0.0.1:8000/someothertask/",
        "locationlists": "http://127.0.0.1:8000/locationlists/",
    }
    

    值得注意的是,您的视图的反向名称现在已从 weather-location-lists 更改为 weather-location-list,但希望这是对可能使用的位置的微小更改。

    【讨论】:

      【解决方案2】:

      路由器仅适用于ViewSet

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-03
        • 2019-03-17
        • 2015-06-05
        • 1970-01-01
        • 1970-01-01
        • 2021-05-30
        • 2020-07-15
        • 1970-01-01
        相关资源
        最近更新 更多