API端点的Django子域配置

时间:2015-02-10 14:00:28

标签: python django url nginx subdomain

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

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

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

http://example.com/control_panel

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

http://api.example.com/tasks

我该怎么做?

提前致谢。

P.S。 该网站将在Gunicorn上运行,nginx作为反向代理。

2 个答案:

答案 0 :(得分:1)

我在使用基于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  

答案 1 :(得分:0)

django-dynamicsites-lite怎么样?并且您的代码将更加干净,因为API和站点位于不同的文件夹中。