问题
I've set up a Django project which makes use of the django-rest-framework
to provide some ReST functionality. The website and the rest functionality are all working fine.
However there is one little problem: I need my API endpoints to point to a different subdomain.
For example when a user visits the website he/she can navigate around normally according to my urls.py
:
http://example.com/control_panel
So far so good.
However when the API is used I want to change that to something more appropriate. So instead of http://example.com/api/tasks
I need this to become:
http://api.example.com/tasks
How should I do that?
Thanks in advance.
P.S. The website will be running on Gunicorn with nginx serving as a reverse proxy.
回答1:
I had a similar issue with a Django based API. I found it useful to write a custom middleware class and use that to control which URLs were served on which subdomains.
Django doesn't really care about subdomains when serving URLs, so assuming your DNS is set up such that api.example.com points to your Django project, then api.example.com/tasks/ will call the expected API view.
The problem is that www.example.com/tasks/ would also call the API view, and api.example.com would serve the home page in a browser.
So a bit of middleware can check that subdomains match up with URLs and raise 404 responses if appropriate:
## 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
回答2:
What about django-dynamicsites-lite. And your code will be more clean because API and site are in different folders.
来源:https://stackoverflow.com/questions/28433536/django-subdomain-configuration-for-api-endpoints