Django redirect() truncating URLs to domain name on production server using HTTPS
Question: I'm running Django 1.8, Python 2.7. I have noticed a problem on my site with
redirects which seems only to affect my production server using HTTPS
protocol, but not staging or dev servers running plain HTTP.

As examples, I've identified two simple things which do not currently work for
me over HTTPS:

  1. Visiting <https://www.eduduck.com/support/thanks> with no trailing slash redirects to <https://www.eduduck.com/> instead of appending a slash and redirecting to <https://www.eduduck.com/support/thanks/> as I would have expected with (default settings) APPEND_SLASH = True.

  2. Submitting a valid support form 'wrongly' redirects to <https://www.eduduck.com/> site base url when using HTTPS but works correctly with HTTP, redirecting to /support/thanks/

It's all routine stuff, or should be. Very perplexed by this; any pointers
most gratefully received. **NB: Problem only appears under HTTPS**

**support/urls.py**

    
    
    from django.conf.urls import url
    from django.views.generic import TemplateView
    
    from . import views
    
    urlpatterns = [
        url(r'^$', views.support, name='support'),
        url(
            r'^thanks/$',
            TemplateView.as_view(template_name ='support/thanks.html')),
    ]
    

**support/forms.py**

    
    
    from django import forms
    
    class SupportForm(forms.Form):
        """General request for support or contact"""
        subject = forms.CharField(max_length = 100)
        email = forms.EmailField(label='Your email')
        message = forms.CharField(widget = forms.Textarea)
    
        def clean_message(self):
            """Sensible messages cannot be too short"""
    
            message = self.cleaned_data['message']
            wc = len(message.split())
            if wc < 4:
                raise forms.ValidationError(
                    "Please muster four or more words of wisdom or woe!"
                )
            return message
    

**support/views.py**

    
    
    from django.core.mail import send_mail
    
    from django.http import HttpResponseRedirect
    from django.shortcuts import render
    from django.template import RequestContext
    
    from .forms import SupportForm
    
    import logging
    logger = logging.getLogger(__name__)
    
    def support(request):
        """Provide a support/contact email form"""
    
        logger.info('Support view')
        if request.method=="POST":
            form = SupportForm(request.POST)
            if form.is_valid():
                cdata = form.cleaned_data
                send_mail(cdata['subject'],
                          cdata['message'],
                          cdata.get('email', 'example@example.com'),
                            ['example@example.com'],
                )
                return HttpResponseRedirect('/support/thanks/')
        else:
            form = SupportForm()
    
        return render(
            request, 
            'support/support.html',
            {'support_form': form}, 
        )
    


Answer: So in the end, yes it was my nginx config. I had an old sites-enabled/default
config file, which I deleted. This made some progress, but I also had to edit
the config file for my production site. The diff for the final (working)
server block looks like this:

    
    
    server {
        - listen [::]:80 default_server; 
        + listen 80 default_server;
        server_name www.example.com;
        return 301 https://$host$request_uri
    }
    

As I mentioned in my earlier comment, despite reading the docs, I still don't
exactly know what is wrong with [::]:80 which I thought was for IPv6
compatibility.

