我已经设置了一个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作为反向代理。
答案 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和站点位于不同的文件夹中。