pythondjangoauthenticationrender-to-response

Django render_to_response not working as expected


Django 1.5 - django-ldap-auth

Trying to figure out how to properly using request_to_context as it only works on the login.html page itself. (user.is_authenticated etc).

After the user gets logged in, it forwards the user to /reboot. From there I want to use {{ user.is_authenticated }} / {{ user.username }}, but nothing shows up(true or false). It is just blank.

On the login.html page itself they work correctly. If I render to the reboot/index.html it does not render the code that I have the index do. I assumed I would be able to call these commands after a user is authenticated. Hopefully I am just missing a small piece to this puzzle.

I have included all of the necessary code. Let me know if you need something else.

Here is my layout.

reboot/form.py

from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm

class LoginForm(forms.Form):
    username    = forms.CharField(label=(u'User Name'))
    password    = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))

views.py

from django.template import Context, loader, RequestContext
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect
from servers.models import Server
from reboot.forms import LoginForm
import paramiko
import socket

def logout_user(request):
    logout(request)
    return HttpResponseRedirect('/status/')

def index(request):
  t = loader.get_template('reboot/index.html')
  servers = Server.objects.all()
  c = Context( {
    'servers': servers,
  })
  return HttpResponse(t.render(c))

def test_ssh_liveness(ssh, name):
  try:
    ssh.connect(name, timeout='1')
    return True
  except socket.timeout:
    # server is down
    return False
  except socket.gaierror:
    # invalid server name
    return False
  except paramiko.SSHException:
    # unknown host key
    return True

def server(request, name):
  ssh = paramiko.SSHClient()
  is_alive = test_ssh_liveness(ssh, name)
  return HttpResponse("You selected server "+name+" and it is "+str(is_alive))

# user login
def login_user(request):
    if request.user.is_authenticated():
        # return HttpResponseRedirect('/reboot/')
        pass
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/reboot/')
        else:
            return render_to_response('login.html', {'form', form}, context_instance=RequestContext(request))
    else:
        ''' user is not submitting the form, show the login form '''
        form = LoginForm()
        context = {'form': form}
        return render_to_response('login.html', context, context_instance=RequestContext(request))

reboot.urls

from django.conf.urls import patterns, url     
from reboot import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    #(r'^$', views.login_user),
    url(r'^server/(?P<name>[^/]+)', views.server, name='server')
)

main url file

from django.conf.urls import patterns, include, url 
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),

    url(r'^reboot/', include('reboot.urls')),
    # Login for reboot 
    (r'^login/$', 'reboot.views.login_user'),
    (r'^logout/$', 'reboot.views.logout_user'),

    url(r'^status/', include('status.urls')),
)

login.html

% extends "base.html" %}
{% block content %}
<p> print {{ user.is_authenticated }}</p>
    <div id="login">
        <form class="form-horizontal" name="LoginForm" action="/login/" method="post">
        {% csrf_token %}
        {% if next %}
            <input type="hidden" name="next" value="{{ next }}" />
        {% endif %}

        <div class="control-group">
            <label class="control-label" for="username">Username</label>
            <div class="controls">
                <input type="text" id="username" name="username" placeholder="Username">
            </div>
        </div>

        <div class="control-group">
            <label class="control-label" for="password">Password</label>
            <div class="controls">
                <input type="password" name="password" id="password" placeholder="Password">
            </div>
        </div>

        <div class="control-group">
            <div class=controls">
                <button type="submit" class="btn">Login</button>
            </div>
        </div>

        </form>
    </div>

{% endblock %}

/reboot/index.html

{% extends "base.html" %}

{% block title %}Server{% endblock %}

{% block content %}
<h2>Server Control Panel</h2>
<h4>Welcome, print {{ user.is_authenticated }}.</h4>
{% if user.is_authenticated %}<p><a href="/logout/">Logout</a></p>{% else %}<a href="/login/">Login</a></p>{% endif %}
    <p class="lead">
    The servers below correspond to servers that you have access to. 
    If you believe there are errors, please <a href="mailto:jz@tripadvisor.com">contact me.</a>
    </p>
<div class="container-fluid">
<table class="table table-hover">
  <thead>
    <tr>
        <th><h4>Hostname</h4></th>
        <th><h4>Commands</h4></th>
    </tr>
  </thead>
  <tbody>
  {% for server in servers %}
    <tr>
        <td><a href="{% url 'server' server.hostname %}" class="btn">{{ server.hostname }}</a></td>
        <td>
            <a href="#" class="btn btn-success">start</a>
            <a href="#" class="btn btn-warning">restart</a>
            <a href="#" class="btn btn-danger">shutdown</a>
        </td>
    </tr>
  {% endfor %}
  </tbody>
</table>
</table>
</div>
{% endblock %}

I appreciate all of your help. I have been stuck on this issue for a few days now and have not been able to figure it out.

John


Solution

  • Your view needs a RequestContext instance (docs), like your login view, so it knows which user is logged in (and other stuff). So instead of:

    def index(request):
        t = loader.get_template('reboot/index.html')
        servers = Server.objects.all()
        c = Context( {
          'servers': servers,
        })
        return HttpResponse(t.render(c))
    

    just make it:

    def index(request):
        servers = Server.objects.all()
        context = {
          'servers': servers,
        }
        return render_to_response('reboot/index.html', context, context_instance=RequestContext(request))
    

    EDIT

    It's not really about the render_to_response. As the import says, that's just a shortcut.

    Django's context processors (basically, functions that add variables to your template context) are request-based, and therefor are only called if you specify a RequestContext, and that includes django.contrib.auth.context_processors.auth, the context processor that includes the user variable into your template.

    The equivalent of your code would be:

    def index(request):
        t = loader.get_template('reboot/index.html')
        servers = Server.objects.all()
        c = RequestContext(request, {
          'servers': servers,
        })
        return HttpResponse(t.render(c))