Python API终结点的Django子域配置

Python API终结点的Django子域配置,python,django,url,nginx,subdomain,Python,Django,Url,Nginx,Subdomain,我已经建立了一个Django项目,它利用Django rest框架来提供一些rest功能。网站和其他功能都运行良好 但是有一个小问题:我需要API端点指向不同的子域 例如,当用户访问网站时,他/她可以根据myURL.py正常导航: http://example.com/control_panel 到目前为止还不错。 然而,当使用API时,我想将其更改为更合适的方式。因此,与其使用http://example.com/api/tasks我需要它成为: http://api.example.com

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

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

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

http://example.com/control_panel
到目前为止还不错。 然而,当使用API时,我想将其更改为更合适的方式。因此,与其使用
http://example.com/api/tasks
我需要它成为:

http://api.example.com/tasks
我该怎么做

提前谢谢

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

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

那怎么办。因为API和站点位于不同的文件夹中,所以您的代码将更加干净。

您有过这样的工作吗?我不敢相信我在搜索中没有找到这个,但我实际上写了一个副本:这里提供的中间件方法对你有用吗?@nicorellius我通过使用Django hosts包成功地让它工作了。在pypi上查找它,但请注意,它目前只在Django 1.7.x上工作。我希望我能帮上忙。@Konos5-非常感谢你的提示!我现在正在整合这个。正是我想要的。。。嘿,配置它有点困难,你遇到了什么提示、技巧或陷阱吗?例如,您是如何处理API URLConf中的
include(router.url)
的?我想您的意思是:
if request.domain in['localhost:8000','testserver']:
(不应该有'not'。