Django: Site-Wide URL Prefix - django

I've built a Django site that will live at the root when it's live. Right now it's functioning perfectly at the IP address. For testing purposes, the client has pointed a proxy url at it, but the url has /folder/path in it, so none of the URL patterns match. I put (/folder/path)? into all the url patterns so they now respond, but all of the links are broken because I'm using the {% url %} tag and while the url patterns will match the optional path, they don't include it in that tag.
Clearly I can just hard-code /folder/path into all of my urls (well, into all of the url includes) until testing is complete, but is there a better way to do this?

You manage this when you deploy your application, by correctly setting the WSGIScriptAlias in your Apache configuration (assuming you're using mod_wsgi, which you should be doing). This is passed on to Django, which then automatically prefixes all URL reverse lookups with the correct value. You shouldn't need to do any manual mucking about with prefixes.

For this purpouse I use URL_PREFIX in settings.py and add it in each include in urls.py. I also add it at the beginning of MEDIA_URL, for all images/css/js links to work. But I would also like to hear about some more tricky solution?

if WSGIScriptAlias doesn't work or you can't set it up for some reason, remember that the include() function in a urlconf adds the prefix to all URLs. you can create an urlconf which includes your current root urlconf and mount it at the prefix, and then point your settings.py file to that urlconf.
Disclaimer: haven't tried this myself, but it should work.

Related

django-comments-xtd not accessible with wagtail? How to troubleshoot?

I have installed django-comments-xtd following the quick start guide in the documentation here.
When I go to access the /comments URL, I only get a 404 error, and the message 'Raised by: wagtail.wagtailcore.views.serve'.
I followed the documentation without issue, and have installed other apps that work fine such as django-machina.
I am using django 1.11.13, python 2.7 and django-comments-xtd 2.1.0.
Why would this particular URL not be accessible? Templates exist in the correct location.
My files are setup exactly the same as in the documentation, happy to provide more info but not sure what to provide right now.
What can I do to try and troubleshoot the problem?
I think you are misreading the documentation and you do not actually have a problem. It just says:
mount the URL patterns of django_comments_xtd in the path /comments/
It does not say that you should access this URL. The fact that, as per your comment, you are not getting a 404 when you are accessing /comments/sent/ indicates that you have set up django-comments-xtd correctly.
For /comments/ to be a valid URL, the django_comments_xtd.urls you included would have to contain an empty URL pattern, like this:
url('', some_view)
If you look at the urls.py of django-comments-xtd, you will see that it does indeed include the urls.py from django-contrib-comments, but this doesn't define an empty URL pattern. So there is no URL pattern that would match /comments/.
The urls definition from django-comments-xtd will have to come before Wagtail's one (i.e. url(r'', include(wagtail_urls))) as it acts as a catch all and will therefore render other urls unreachable.
just food for thought. The email confirmation template uses
http://{{ site.domain }}{{ confirmation_url|slice:":40" }}...
You want to make sure your site.domain matches whatever your are using for development. This just fixed this error for me. I had a different domain setup in Django Admin

Best practices for path-agnostic links in Django?

What is the best way to code html links in a Django application
which is intended to be distributed to other users and
where it cannot be known in advance what the final
URL path to the application will be?
Here are some links I am currently using:
<li>By Date</li>
<li>Trends</li>
This works fine when the app is configured like this in mysite/urls.py to
be in the root path.
url(r'^', include('myapp.urls')),
But if you change mysite/urls.py to run the app in a different path:
url(r'^myapp/', include('myapp.urls')),
then the links break. This seems like it ought to be a common scenario but I have been unable to discover how to solve it cleanly.
You want url tag:
Returns an absolute path reference (a URL without the domain name) matching a given view function and optional parameters. This is a way to output links without violating the DRY principle by having to hard-code URLs in your templates

Django+WSGI: Use app at subpath without changes

I'd like to serve a Django application from a subdirectory (for example http://www.stackoverflow.com/django_app/).
I've set up mod_wsgi to serve the page via
WSGIScriptAlias /django_app PATH_TO_DJANGO/wsgi.py
How can I specify settings like LOGIN_URL, STATIC_URL, MEDIA_URL, etc. so Django respects the relative path?
If set STATIC_URL it to "/static/" it tries to reference resources at http://www.stackoverflow.com/static/ instead of http://www.stackoverflow.com/django_app/static/.
But if I set it to "static" (without a leading slash) it is interpreted relative to any URL which is also wrong. For example, the admin page at
http://www.stackoverflow.com/django_app/admin/
tries to load the files from
http://www.stackoverflow.com/django_app/admin/static/
I haven't found a way to tell Django to use http://www.stackoverflow.com/django_app/static without explicitly hardcoding the prefix /django_app within the settings (which IMHO violates the DRY principle because it is already specified in the mod_wsgi-config).
It also prohibits serving the same project under different URLs without modifying the project, which seems odd.
There is no way for it to be automatic. The URLs in those few variables, and LOGOUT_URL, are not automatically prefixed with the SCRIPT_NAME which is passed in with scripts and which identifies the mount point.

Apache | Django: How to run websites on the back of a base URL?

I've got a base url. http://baseurl.com/
I'm trying to run projects on the back of it. For example
http://baseurl.com/mongoose/
The projects run but the URL don't work properly because they all
reference the base url. So for 'About Me' page it points to
http://baseurl.com/about instead of http://baseurl.com/mongoose/about
Is this something i need to change in django or apache? Is what I'm
trying to do even possible?
Coming from an IIS .net background I know that in IIS you can "Create and application" within a site which essentially does what I'm trying to achieve now with Apache and Django.
Thanks
You shouldn't need to do anything. Apache is supposed to be setting a request header called SCRIPT_NAME, which is your base URL, and all URL reversing takes that into account.
How are you creating these URLs in your templates?
Update
So your problem is with getting the URLs of Flatpages. The issue is that the normal way of calculating URLs dynamically, so that they do take SCRIPT_NAME into account - using the reverse() function or the {% url %} tag - doesn't work with Flatpages, because they are not dispatched via urls.py but via a custom middleware which fires on a 404.
So instead of using that middleware, I would use the urls.py mechanism to dispatch to flatpages. Remove the flatpagemiddleware from your settings.py, and in urls.py at the end of your patterns add this:
url(r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage', name='flatpage'),
Now, in your templates, you can do:
<a href="{% url flatpage page.url %}">
and it should work correctly.
Check any urls.py in the project(s) to see if they expect to be top-level. But if the application outputs links like /something then it's going to mean the root directory. The application should be reversing a view/parameter into a URL, which would allow you to move it around. If you wrote the apps, check out reverse in django.core.urlresolvers

How to make Django url dispatcher use subdomain?

I have a vague idea on how to solve this, but really need a push :)
I have a Django app running with apache (mod_wsgi). Today urls look like this:
http://site.com/category/A/product/B/
What I would like to do is this:
http://A.site.com/product/B
This means that the url dispatcher some how needs to pick up the value found in the subdomain and understand the context of this instead of only looking at the path. I see two approaches:
Use .htaccess and rewrites so that a.site.com is a rewrite. Not sure if this does the trick since I don't fully understand what the django url dispatcher framework will see in that case?
Understanding how the url dispatcher DO work I could write a filter that looks at valid sub domains and provides this in a rewritten format to the url dispatcher code.
Any hints or solutions are very much appreciated! Thanks.
Have you looked at django.contrib.sites? I think a combination of that, setting SITE_ID in your settings.py, and having one WSGI file per "site" can take care of things.
EDIT: -v set.
django.contrib.sites is meant to let you run multiple sites from the same Django project and database. It adds a table (django.contrib.sites.models.Site) that has domain and name fields. From what I can tell, the name can mean whatever you want it to, but it's usually the English name for the site. The domain is what should show up in the host part of the URL.
SITE_ID is set in settings.py to the id of the site being served. In the initial settings.py file, it is set to 1 (with no comments). You can replace this with whatever code you need to set it to the right value.
The obvious thing to do would be to check an environment variable, and look up that in the name or domain field in the Site table, but I'm not sure that will work from within the settings.py file, since that file sets up the database connection parameters (circular dependency?). So you'll probably have to settle for something like:
SITE_ID = int(os.environ.get('SITE_ID', 1)
Then in your WSGI file, you do something like:
os.environ['SITE_ID'] = 2
and set that last number to the appropriate value. You'll need one WSGI file per site, or maybe there's a way to set SITE_ID from within the Apache setup. Which path to choose depends on the site setup in question.
The sites framework is most powerful where you use Site as the target of a ForeignKey or ManyToManyField so that you can link your model instances (i.e. records) to specific sites.
Mikes solution is correct if you want to have multiple sites with same apps with different content (sites module) on multiple domains or subdomains, but it has a drawback that you need to be running multiple instances of the Django process.
A better solution for the main problem about multiple domains or subdomains is to use a simple middleware that handles incoming requests with the process_request() function and changing the documented urlconf attribute (link) of the request object to the URLconf you want to use.
More details and an example of the per-request or per-domain URL dispatcher can be found at:
http://gw.tnode.com/0483-Django/
Try adding a wildcard subdomain: usually *.