【问题标题】:Django subdomain configuration for API endpointsAPI 端点的 Django 子域配置
【发布时间】:2015-04-10 14:17:21
【问题描述】:

我已经建立了一个 Django 项目,它利用 django-rest-framework 来提供一些 ReST 功能。网站和其他功能都运行良好。

但是有一个小问题:我需要我的 API 端点指向一个不同的子域

例如当用户访问该网站时,他/她可以根据我的urls.py正常导航:

http://example.com/control_panel

到目前为止一切顺利。 但是,当使用 API 时,我想将其更改为更合适的内容。所以我需要这个而不是http://example.com/api/tasks

http://api.example.com/tasks

我该怎么做?

提前致谢。

附: 该网站将在 Gunicorn 上运行,并使用 nginx 作为反向代理。

【问题讨论】:

  • 你有没有得到这个工作?我不敢相信我在搜索中没有找到这个,但实际上我写了一个副本:stackoverflow.com/questions/29807091/… 这里提供的中间件方法对你有用吗?
  • @nicorellius 我设法通过使用 Django-hosts 包让它工作。在 pypi 上查找它,但请注意它目前仅适用于 Django 1.7.x。我希望我能帮上忙。
  • @ Konos5 - 非常感谢您的提示!我现在正在努力整合它。正是我正在寻找的...嘿,配置它有点困难,您遇到任何提示、技巧或陷阱?例如,您是如何处理 API URLConf 中的 include(router.urls) 的?

标签: python django url nginx subdomain


【解决方案1】:

django-dynamicsites-lite 呢。而且您的代码会更干净,因为 API 和站点位于不同的文件夹中。

【讨论】:

    【解决方案2】:

    我在使用基于 Django 的 API 时遇到了类似的问题。我发现编写自定义中间件类并使用它来控制在哪些子域上提供哪些 URL 很有用。

    Django 在提供 URL 时并不真正关心子域,因此假设您的 DNS 设置为 api.example.com 指向您的 Django 项目,那么 api.example.com/tasks/ 将调用预期的 API 视图.

    问题在于 www.example.com/tasks/ 也会调用 API 视图,而 api.example.com 会在浏览器中提供主页。

    因此,一些中间件可以检查子域是否与 URL 匹配,并在适当时引发 404 响应:

    ## settings.py
    
    MIDDLEWARE_CLASSES += (
        'project.middleware.SubdomainMiddleware',
    )
    
    
    ## middleware.py
    
    api_urls = ['tasks']  # the URLs you want to serve on your api subdomain
    
    class SubdomainMiddleware:
        def process_request(self, request):
            """
            Checks subdomain against requested URL.
    
            Raises 404 or returns None
            """
            path = request.get_full_path()  # i.e. /tasks/
            root_url = path.split('/')[1]  # i.e. tasks
            domain_parts = request.get_host().split('.')
    
            if (len(domain_parts) > 2):
                subdomain = domain_parts[0]
                if (subdomain.lower() == 'www'):
                    subdomain = None
                domain = '.'.join(domain_parts[1:])
            else:
                subdomain = None
                domain = request.get_host()
    
            request.subdomain = subdomain  # i.e. 'api'
            request.domain = domain  # i.e. 'example.com'
    
            # Loosen restrictions when developing locally or running test suite
            if not request.domain in ['localhost:8000', 'testserver']:
                return  # allow request
    
            if request.subdomain == "api" and root_url not in api_urls:
                raise Http404()  # API subdomain, don't want to serve regular URLs
            elif not subdomain and root_url in api_urls:
                raise Http404()  # No subdomain or www, don't want to serve API URLs
            else:  
                raise Http404()  # Unexpected subdomain
            return  # allow request  
    

    【讨论】:

    • 我想你的意思是:if request.domain in ['localhost:8000', 'testserver']:('not' 不应该在那里)。
    猜你喜欢
    • 2018-06-02
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 2020-10-15
    • 2019-05-04
    • 2012-04-11
    相关资源
    最近更新 更多