'module' object is not iterable - python

My Django project is returning a TypeError: 'module' object is not iterable.
I know this type of question is already being asked in community, but none of previous questions could fixed my issue.
perhaps I don't understand something basic, as I'm a novice who freshly learning Python and Django. does anyone can help me to solve this issue?
I created a model as following.
from django.db import models
# Create your models here.
class Article(models.Model):
content = models.CharField(max_length=200)
written_date = models.DateTimeField('date written')
def __unicode__(self):
return self.content
Following is view.py
# Create your views here.
from blog.models import Article # Article data models
from django.shortcuts import render # shortcuts to call template
from django.http import HttpResponseRedirect # Redirection Module
from django.template import context
from django.utils import timezone # time Module
# blog.views.index
# retrieve all content and display in reverse of order of written_date
# call the template after sorting.
def index(request):
all_articles = Article.objects.all().order_by('-written_date')
return render({'all_articles' : all_articles, 'message' : 'Write something!'},
'blog/index.html', context)
# blog.views.submit
# Receive POST request submitted from user FORM, save the request
# redirect user to index.html
def submit(request):
try:
cont = request.POST['content']
except (KeyError):
return render({'all_articles' : all_articles, 'message' : 'Failed to read content'},
'blog/index.html', context)
else:
article = Article(content=cont, written_date=timezone.now())
article.save()
return HttpResponseRedirect('/blog')
# blog.views.remove
# delete content which has primary key matched to article_id
# redirect user after deleting content
def remove(request, article_id):
article = Article.objects.get(pk=article_id)
article.delete()
return HttpResponseRedirect('/blog')
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>One Line Blog</title>
<link rel="stylesheet" href="{{ STATIC_URL }}styles/blog.css" type="text/css">
</head>
<body>
<div id="header">
<h2>One Line Blog</h2>
</div>
<div id="writer">
<div>
{% if message %}<p><strong>{{ message }}</strong></p>{% endif %}
</div>
<form action="/blog/submit" method="post">
{% csrf_token %}
<input type="text" max-length=200 style="width:500px;" name="content">
<input type="submit" value="Submit">
</form>
</div>
<div>
{% if all_articles %}
<table>
<tr>
<th>No. </th>
<th width="300px">Content</th>
<th>Date</th>
<th>Delete</th>
</tr>
{ % for article in all_articles %}
<tr>
<td>{{ article.id }}</td>
<td>{{ article.content }}</td>
<td>{{ article.written_date }}</td>
<td align="center">[x]</td>
</tr>
{ % endfor %}
</table>
{% else %}
<p>No articles available</p>
{% endif %}
</div>
</body>
</html>

The signature of render is:
render(request, template_name, context=None, content_type=None, status=None, using=None)
You, however, call it in your index view:
return render({'all_articles' : all_articles, 'message' : 'Write something!'},
'blog/index.html', context)
where you pass a dict as request (bad enough) and, which causes the error, as third positional argument (which should be a dict) you pass a variable by the name of context which is a module that you have imported via
from django.template import context
Change it to
return render(request, 'blog/index.html',
context={'all_articles': all_articles, 'message': 'Write something!'})
You made the same mistake in your submit view.

Related

Notification when a certain point in time is exceeded (Python)

I would like to create a To-Do list in which I can schedule date and time of each task. My goal is to get some sort of response whenever the supplied datetime is equal to the current time. For example I scheduled Do laundry for Monday at 6pm on a Saturday evening. Two days later (on Monday at 6pm) I would like to get a notification that I should Do laundry.
Notice that the key idea can be found in the index() function in views.py in the first rows including the if-statement.
Here is my code:
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("<int:aufgabenzettel_id>", views.details, name="details"),
path("add/", views.add, name="add"),
path("delete/<int:aufgabenzettel_id>", views.delete, name="delete"),
path("edit/<int:aufgabenzettel_id>", views.edit, name="edit"),
path("update/<int:aufgabenzettel_id>", views.update, name="update")
]
models.py
from django.db import models
# Create your models here.
class Aufgabenzettel(models.Model):
Aufgabeselbst = models.CharField(max_length=64)
Datum = models.DateTimeField(auto_now_add=True)
Geplant = models.DateTimeField(auto_now_add=False, auto_now=False)
def __str__(self):
return f"{self.Aufgabeselbst}"
views.py (the important part can be found in the index function in the first rows including the if-statement)
from django.db.models.fields import DateTimeField
from django.http.response import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.utils import timezone
from datetime import datetime
from .models import Aufgabenzettel
# Create your views here.
def index(request):
now = datetime.now()
Aufgaben_items = Aufgabenzettel.objects.all().order_by("-Geplant") #arrange objects in the correct order
for Aufgabenzettel.Geplant in Aufgaben_items: #run through the loop and...
if Aufgabenzettel.Geplant == now: #...search for items in the database where the scheduled time ("Geplant") is equal to the current time
return render (request, "aufgabenzettel/add.html") #response in any way e.g. by returning the add.html
return render(request, "aufgabenzettel/index.html", {
"Aufgabenliste":Aufgabenzettel.objects.all(), #currently not used
"Aufgaben_items":Aufgaben_items
})
def details(request, aufgabenzettel_id):
aufgabenzettel = Aufgabenzettel.objects.get(pk=aufgabenzettel_id)
creationDate = aufgabenzettel.Datum
dueDate = aufgabenzettel.Geplant
return render(request, "aufgabenzettel/details.html", {
"details":aufgabenzettel,
"creationDate": creationDate,
"dueDate":dueDate
})
def add(request):
addDatum = timezone.now()
if request.method == "POST":
Aufgabe = request.POST["Hinzufügen"]
geplantes_datum = request.POST["DatumFeld"]
Aufgabenzettel.objects.create(Aufgabeselbst=Aufgabe , Datum=addDatum, Geplant=geplantes_datum) #Aufgabenname und Aufgabendatum erstellen
return HttpResponseRedirect(reverse("index"))
return render(request, "aufgabenzettel/add.html")
def delete(request, aufgabenzettel_id):
aufgabenzettel = Aufgabenzettel.objects.get(pk=aufgabenzettel_id)
aufgabenzettel.delete()
return HttpResponseRedirect(reverse("index"))
def edit(request, aufgabenzettel_id):
aufgabenzettel = Aufgabenzettel.objects.get(pk=aufgabenzettel_id)
return render(request, "aufgabenzettel/edit.html", {
"details":aufgabenzettel
})
def update(request, aufgabenzettel_id):
if request.method == "POST":
Aufgabe = Aufgabenzettel.objects.get(pk=aufgabenzettel_id)
Aufgabe.Aufgabeselbst = request.POST["Bearbeiten"]
Aufgabe.save()
return HttpResponseRedirect(reverse("index"))
return render(request, "aufgabenzettel/edit.html")
index.html
{% extends "aufgabenzettel/layout.html" %}
{% block body %}
<h1 id="MeineAufgaben">Meine Aufgaben</h1>
<table>
{% for Aufgabeselbst in Aufgaben_items %}
<tr>
<td>
<a href="{% url 'details' Aufgabeselbst.id %}">
{{ Aufgabeselbst }}
</a>
</td>
<td>
<form action="{% url 'delete' Aufgabeselbst.id %}" method="post">
{% csrf_token %}
<button type="submit" id="löschenbtn">Löschen</button>
</form>
</td>
<td>
<form action="{% url 'edit' Aufgabeselbst.id %}" method="post">
{% csrf_token %}
<button type="submit" value="{{ details }}" class="bearbeitenbtn">Bearbeiten</button>
</form>
</td>
</tr>
{% endfor %}
</table>
<h2>
Neue Aufgabe erstellen
</h2>
{% endblock %}
add.html
{% extends "aufgabenzettel/layout.html" %}
{% block body %}
<h1>Füge eine neue Aufgabe hinzu!</h1>
<form action="{% url 'add' %}" method="post">
{% csrf_token %}
<input type="text" name="Hinzufügen" placeholder="Neue Aufgabe">
<input type="datetime-local" name="DatumFeld">
<button type="submit" id="Hinzufügen">Hinzufügen</button>
</form>
{% endblock %}
details.html
{% extends "aufgabenzettel/layout.html" %}
{% block body %}
<h1>{{ details }}</h1>
<h3>Erstellt: {{ creationDate }}</h3>
<h2>Geplant: {{ dueDate }}</h2>
Zurück zu Aufgabe
{% endblock %}
edit.html
{% extends "aufgabenzettel/layout.html" %}
{% block body %}
<h2>Bearbeite deine Aufgabe "{{ details }}"</h2>
<form action="{% url 'update' details.id %}" method="post">
{% csrf_token %}
<input type="text" name="Bearbeiten" value="{{details}}">
<button type="submit" class="bearbeitenbtn">Bearbeiten</button>
</form>
Zurück zu Aufgabe
{% endblock %}
layout.html
{% load static %}
<!DOCTYPE html>
<html lang="de">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aufgabenzettel</title>
<link rel="stylesheet" href="{% static '/css/main.css' %}">
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
I don't get an Error or anything but the code is not running as expected. I just want the index function to loop through each element in the database Aufgabenzettel in models.py and if it detects an element where the scheduled time corresponds with the current time some sort of action (in this case a redirect to add.html is ecpected) should happen. However I don't get any such response...
Like always, I appreciate every kind of solution or help!
You're comparing datetimes the wrong way and that is why your if condition is failing (Aufgabenzettel.Geplant == now) .
Try comparing them like this:
In [1]: from datetime import datetime
In [2]: past = datetime.now()
In [3]: present = datetime.now()
In [4]: present.strftime('%Y-%m-%d %H:%M:%S') == past.strftime('%Y-%m-%d
%H:%M:%S')
Out[17]: False
In [5]: present.strftime('%Y-%m-%d %H:%M') == past.strftime('%Y-%m-%d %H:%M')
Out[2]: True
Usually datetimes are compared after converting them to iso format. You can also use the function .isoformat() from timezone.
Picked it up from here: How to compare two Datetime field in Django

displaying other attribute values if one is known in django template

i have this app in django that i'm trying to make. this is the index.html page
<html>
<head>
<title>The index page</title>
</head>
<body>
<h1>Choose the name of student</h1>
<form action= "{% url 'detail' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<select name="namedrop">
{% for name in student_list %}
<option value={{name.stuname}}>{{name.stuname}}</option>
{% endfor %}
</select>
<input type="submit" name="submit">
</form>
</body>
</html>
and this is the detail.html page to which it is directed when we select a name and click submit button...
<!DOCTYPE html>
<html>
<head>
<title>Details of student </title>
</head>
<body>
<p>hello {{name}}</p>
<style type="text/css">
p
{
color: blue;
}
</style>
</body>
</html>
but it only shows "hello neha" if the name selected is "neha"... but i want it to print all the details of this student from the table student...this is models.py...
from django.db import models
class course(models.Model):
cid=models.IntegerField(unique=True,default=0)
cname=models.CharField(max_length=50)
def __unicode__(self):
return self.cname
class Meta:
db_table= "course"
class student(models.Model):
stuid=models.IntegerField(default=0)
stuname=models.CharField(max_length=50)
cid=models.ForeignKey(course,to_field='cid',on_delete=models.CASCADE)
def __unicode__(self):
return self.stuname
class Meta:
db_table= "student"
class subject(models.Model):
sid=models.IntegerField(default=0)
sub=models.CharField(max_length=50)
cid=models.ForeignKey(course,to_field='cid',on_delete=models.CASCADE)
class Meta:
db_table= "subject"
def __unicode__(self):
return self.sub
this is views.py
from .models import student
from django.http import Http404
from django.shortcuts import render
from django.template import loader
from django.http import HttpResponse
def index(request):
student_list=student.objects.all()
template = loader.get_template('studinfo/index.html')
context= { 'student_list' : student_list, }
return HttpResponse(template.render(context, request))
def detail(request):
if request.method=='POST':
name=request.POST['namedrop']
idd=student.objects.all
return render(request, 'studinfo/detail.html', {'name':name})
also i want it to display all the subjects that "neha" has through the details.html page...how do i do that?
you need to select the student with the following query in your view detail:
student = student.objects.filter(stuname=name)[0]
and add the result to the context :
return render(request, 'studinfo/detail.html', {'name':name, 'student': student})
Then in your template, you can call
{{student.stuname}} or {{student.cid}} ...
In your index template you are passing the name in the form, and just use it in the view to pass it along to the detail template. You need to get the student object and pass it to the detail template, so you have accesss to all its fields. You could start by passing the id in the form, instead of the name:
{% for student in student_list %}
<option value={{ student.id }}>{{ student.stuname }}</option>
{% endfor %}
Then in the view you can do something like this (you would probably want to add more sanity checks, like making sure the student exists):
def detail(request):
if request.method=='POST':
student_id = request.POST['namedrop']
student_instance = student.objects.get(pk=student_id)
idd=student.objects.all
return render(request, 'studinfo/detail.html', {'student': student_instance})
Now in the detail template you have access to the student object and can use all its attributes (e.g. {{ student.stuname }}).
Since there is no direct connection between students and subjects, you have to go through the course:
{% for subject in student.cid.subject_set.all %}
{{ subject }}
{% endfor %}

Django let User Update TextField value on Site via forms?

I hope someone can give me a little help on how to do the following with Django (excuse me if I don't explain everything correct, still new to Django and don't know about a lot of things) :
I have a table of Movies, those Movies have a "Description" Datafield, where when they click on it a form opens up with the current description of the movie. If they double click on this description they are allowed to change it and then save the value. I've made a small gif to visualize the idea:
At least thats the basic Idea behind this, so far I've managed to make most of the things run, but sadly not the Django part where the "new" data from the user is send to the Databank and replaces the old data of the Description.
So could someone explain to me how I can make that work? I know that I'd probably have to write a function to my views.py and then create a new url pattern, but I just can't figure out how exactly. So any help is welcome! Below is my code (I hope I've included every file you guys need):
views.py
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from django.views.generic.list import ListView
from .models import *
class AllMovies(generic.ListView):
model = Movie
template_name = "consilium/index.html"
context_object_name = "latest_movie_list"
class MovieDetails(generic.DetailView):
model = Movie
template_name = "consilium/detail.html"
urls.py
from django.conf.urls import url
from . import views
from .models import *
from django.views.generic.list import ListView
app_name = "consilium"
urlpatterns = [
url(r'^$', views.AllMovies.as_view(), name="index"),
url(r'^(?P<slug>[\w_0-9]+)/$', views.MovieDetails.as_view(), name='detail'),
]
models.py
from django.db import models
from decimal import Decimal
from django import forms
from django.contrib import admin
class Movie(models.Model):
// removed the other models for better overview
description = models.TextField('Movie Description')
def __str__(self):
return self.title
index.html
{% extends "consilium/base.html" %}
{% block body %}
<table class="table">
<thead>
<tr>
<th></th>
<th colspan="2">My Movielist</th>
<th>
</tr>
<tr>
<th></th>
<th>TITLE</th>
<th>GENRE</th>
<th>RELEASE DATE</th>
<th>DIRECTOR</th>
<th>DESCRIPTION</th>
<th>RUNTIME</th>
<th>STATUS</th>
<th>IMDB</th>
</tr>
</thead>
<tbody>
{% if latest_movie_list %}
{% for movie in latest_movie_list %}
<tr>
<td></td>
<td>
<a href="{% url 'consilium:detail' movie.slug %}" data-toggle="popover" data-placement="left" data-content='<img class="title-image" src="{{movie.image.url}}"/>'>{{ movie.title }}</a>
</td>
<td>{{ movie.get_genre_display}}</td>
<td>{{ movie.date}}</td>
<td>{{ movie.director}}</td>
<td id="icn-change" data-toggle="collapse" data-target=".demo{{ forloop.counter }}">
Description <i class="fa fa-caret-right"></i>
</td>
<td>{{ movie.runtime}} min</td>
<td>{{ movie.get_status_display}}</td>
<td>{{ movie.imdb}}</td>
</tr>
<tr>
<td></td>
<td class="hiddenRow" colspan="8">
<div class="container collapse demo{{ forloop.counter }}">
<div class="row justify-content-center">
<div class="col">
<form method="post" id="usrform">{% csrf_token %}
<textarea id="text" class ="form-control" readonly="true" onkeydown="expandtext(this)" ondblclick="this.readOnly='';">{{movie.description}}</textarea>
</form>
</div>
</div>
<div class="row justify-content-center">
<div class="col align-self-start">Double Click to Edit</div>
<div class="col align-self-end">
<input type="submit" id="set" class="pull-right"/>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td>No Movies are available.</td>
</tr>
{% endif %}
</tbody>
</table>
{% endblock %}
script.js
// removed all other code for overview
// replace description text with user input
$('#set').click(function() {
var test = $('#text').val();
localStorage.setItem("test", test);
});
$('#text').text(localStorage.getItem("test"));
I hope I didn't miss anything, thanks for everyone who can help me!
I worked on a similar project, and here is what I did.
from django.forms.models import model_to_dict
#login_required
def edit_profile(request):
profile, created = ClientProfile.objects.get_or_create(user_id=request.user.id)
if request.method == 'POST':
form = ProfileSubmissionForm(request.POST, instance=profile)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('jobs:list'))
else:
profile_dict = model_to_dict(profile)
form = ProfileSubmissionForm(profile_dict)
return render(request, 'jobs/profile.html', {'form': form})
Essentially, the model_to_dict renders the values stored in the database in the form. The instance=profile makes sure I'm updating the form and not creating a new object.
Figured it out thanks to the great help of the pythondev slack community!
views.py: getting the description field of my Movie Model
class MovieUpdateForm(forms.ModelForm):
class Meta:
model = Movie
fields = ['description']
reverse_lazy is important, so that when I click on my button it won't redirect me to consilium(my appname)/2/update and stays on the index site where I have my table
class MovieUpdateView(UpdateView):
model = Movie
form_class = MovieUpdateForm
success_url = reverse_lazy('consilium:index')
urls.py:
url(r'^(?P<pk>[0-9]+)/update/$', views.MovieUpdateView.as_view(), name='movie_update'),
here it was important to put this before my slug url pattern I had in my urls.py, otherwise it didn't work:
url(r'^(?P<slug>[\w_0-9]+)/$', views.MovieDetails.as_view(), name='detail'),
My form in my html: using pk=movie.pk so it will grab the correct movie and giving my textarea the name of "description" so my method knows where the data is coming from
<form action="{% url 'consilium:movie_update' pk=movie.pk %}" method="post" id="usrform">{% csrf_token %}
<textarea id="text" class ="form-control" name="description" readonly="true" onkeydown="expandtext(this)" ondblclick="this.readOnly='';">{{movie.description}}</textarea>
<input type="submit" id="set" class="pull-right"/>
</form>

Download a text/csv file from django app that populates HTML table from a database query

I currently have a django app which I can search to query my database which populates a html table from a query.
My app_home.html looks like this:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>RESULTS APP</title>
</head>
<form method="get" action="results/">
<div class="SearchBar"><input type="text" name="lab_number"></div>
<input class='input_button' type='submit'>
</form>
<body></body>
</html>
This is my views.py:
def from_samrun(request):
if request.GET:
lab_query = request.GET['lab_number']
var_list = VarSamRun.objects.filter(sample=lab_query)
if var_list:
return render(request, 'results/varlist.html', {'var_list': var_list})
else:
return render(request, 'results/varlist.html', {'query': [sam_query]})
else:
return render(request, 'results/varlist.html' {'error': 'Error'})
which takes me to my varlist.html template:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head><title>Results page</title></head>
<body>
<div>
{% if var_list %}
{% for v in var_list %}
<tr>
<td class='varsrow' width='100'>{{v.sample}}</td>
<td class='varsrow' width='100'>{{v.gene}}</td>
<td class='varsrow' width='200'>{{v.variant}}</td>
<td class='varsrow' width='150'>{{v.cds}}</td>
<td class='varsrow' width='150'>{{v.protein}}</td>
<td class='varsrow' width='200'>{{v.consequence}}</td>
<td class='varsrow' width='200'>{{v.run}}</td>
<td class='varsrow' width='300'>{{v.annotation}}</td>
</tr>
{% endfor %}
{% elif query %}
<h5>Search using: "
{% for q in query %}
{{q}}
{% endfor %}
" did not return any results</h5>
{% else %}
<h5>{{annotation}}</h5>
{% endif %}
</table>
</div>
</body>
</html>
my urls are:
urlpatterns = [
url(r'^results/$', views.results_app, name='results_app'),
url(r'results/varlist/$', views.from_samrun, name='from_samrun'),
I want to have a download button on my varlist.html page so that when the table is displayed the user can choose to download - export to a csv file. I am aware of how to write data to a csv and download it using another view:
def download_view(request):
response = HttpResponse('')
response['Content-Disposition'] = 'attachment; filename=file.csv'
writer = csv.writer(response, dialect=csv.excel)
writer.writerow(some_random_data_list)
return response
and add a form button to download to my varlist.html page:
<form action ='download' method='POST'>
{% csrf_token %}
<input type='hidden'>
<input type='submit' value='Download'>
</form>
but I have no idea how to pass the information from my first view to my download view, or pass the html table info as an object to my download view.
(i tried passing {{var_list}} as a value in this html form, extracting the data from it and creating a new query object but this does not work for every table as they are too large.
Is there a way to pass my var_list object from the first view to download view? How can I go about doing this?
Thanks
In fact you are requesting the same set of data from your site. The only thing changing is the format. So normally you just want to request the same page with a GET parameter like ?format=csv. So your view function would look like this:
def from_samrun(request):
if request.GET:
lab_query = request.GET['lab_number']
var_list = VarSamRun.objects.filter(sample=lab_query)
if request.GET['format'] == 'csv':
response = HttpResponse('')
response['Content-Disposition'] = 'attachment; filename=file.csv'
writer = csv.writer(response, dialect=csv.excel)
writer.writerow(some_random_data_list)
return response
if var_list:
return render(request, 'results/varlist.html', {'var_list': var_list,'lab_query':lab_query})
else:
return render(request, 'results/varlist.html', {'query': [sam_query]})
else:
return render(request, 'results/varlist.html' {'error': 'Error'})
And your template:
<form method='GET'>
<input type='hidden' name='format' value='csv'>
<input type='hidden' name='lab_query' value={{lab_query}}>
<input type='submit'>
</form>
You can write URL route for your download action. Point it to download_view view in urls.py
Maybe the fastest solution will be plugin:
jQuery Datatables
And some easy setup for your page.

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>Logout</p>{% else %}Login</p>{% endif %}
<p class="lead">
The servers below correspond to servers that you have access to.
If you believe there are errors, please contact me.
</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>{{ server.hostname }}</td>
<td>
start
restart
shutdown
</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
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))

Categories

Resources