Graphs are a pain in the ass. I first attempted to get PYOFC2 to work about a year ago and gave up, I just didn't care enough. Now I want graphs, and have figured out how to use it (at least for a pie chart). urls.py
from django.conf.urls.defaults import *
from django.conf import settings
# the chart data views
urlpatterns = patterns('yourapp.views',
('^data/$','chart_data_two'),
)
urlpatterns += patterns('django.views.generic.simple',
(r'^$', 'direct_to_template', {'template': 'index.html'}),
)
templates/index.html
Chart!
<h1>Pie Chart!</h1>
<div id="chart_demo" class="chart"> </div>
ls -l static/*
-rwxr-xr-x 1 akonkol akonkol 773 2011-03-02 16:08 expressInstall.swf
-rw-r--r-- 1 akonkol akonkol 263109 2011-03-02 16:08 open-flash-chart.swf
-rw-r--r-- 1 akonkol akonkol 9759 2011-03-02 16:08 swfobject.js
yourapp/views.py
from django.http import HttpResponse
from pyofc2 import *
import random
import time
def chart_data_two(request):
t = title(text='Crapface Graph')
p1 = pie()
values = [ pie_value(label="crap", value=4), pie_value(label="face", value=20)]
p1.values = values
chart = open_flash_chart()
chart.title = t
chart.add_element(p1)
return HttpResponse(chart.render())
Produces:
References demodjofc2_demo
I recently used django-tagging for a project and ran into the following error when trying to use this package's template tags: "Invalid block tag: 'tag_cloud_for_model' " To use this package's template tags (such as tag_cloud_for_model) you must load the template tag code as such: {% load tagging_tags %} It's not in the documentation...
I'm working on a new project and decided to use slugs to access object information. The built-in in "slugify" does not generate unique slugs for objects, but I found a solution. Overriding the save method allows us to check to see if there are any other objects which have the same slug such as "how-to-make-a-table" and if there are we append a number to it such as "how-to-make-a-table-2." Below is a real-world example of a model "Project" which has pretty typical fields in it and the code to generate a unique slug. file: /myproject/myapp/models.py
from django.contrib.auth.models import User
from sorl.thumbnail import ImageField
import datetime
import re
class Project(models.Model):
title = models.CharField(max_length=255,blank=True)
description = models.TextField(blank=True)
photo = ImageField(upload_to=get_project_upload_path, blank=True, null=True)
author = models.ForeignKey(User, editable=False,blank=True, null=True)
pub_date = models.DateTimeField(editable=False, blank=True)
slug = models.SlugField(unique=True,blank=True)
def save(self, *args, **kwargs):
#set pub_date as right now
self.pub_date=datetime.datetime.now()
#As long as this object does NOT have a slug
if not self.slug:
from django.template.defaultfilters import slugify
#Take the title and replace spaces with hypens, make lowercase
potential_slug = slugify(self.title)
self.slug = potential_slug
while True:
try:
#try to save the object
super(Project, self).save(*args, **kwargs)
#if this slug already exists we get an error
except IntegrityError:
#match the slug or look for a trailing number
match_obj = re.match(r'^(.*)-(\d+)$', self.slug)
#if we find a match
if match_obj:
#take the found number and increment it by 1
next_int = int(match_obj.group(2)) + 1
self.slug = match_obj.group(1) + "-" + str(next_int)
else:
#There are no matches for -# so create one with -2
self.slug += '-2'
#different error than IntegrityError
else:
break
def __unicode__(self):
return self.title
Everyone uses django-registration for... registration... however.. you may get this error:
TypeError at /accounts/register/ register() takes at least 2 non-keyword arguments (1 given)
Here's what your urls.py should look like for the /accounts/register/ url: urls.py
from django.conf.urls.defaults import *
from registration.forms import RegistrationFormUniqueEmail
urlpatterns = patterns('',
(r'^accounts/register/', 'registration.views.register', {'form_class':RegistrationFormUniqueEmail,'backend':'registration.backends.default.DefaultBackend' }),
)
Enabling tagging on models is easy when you use django-tagging. However, I also have a search feature which is powered by Haystack and Whoosh. I wanted to be able to search for objects by the tags that are associated with them. You need to use the following in your haystack SearchIndex model:
tags = indexes.MultiValueField(indexed=True, stored=True)
Full Example
myproject/myapp/models.py
from django.db import models,
from tagging.fields import TagField
class Template(models.Model):
name = models.CharField(max_length=100)
pub_date = models.DateTimeField(editable=False, blank=True)
description = models.TextField(blank=True)
slug = models.SlugField(unique=True,editable=False,blank=True,null=True)
tags = TagField()
myproject/myapp/search_indexes.py
import datetime
from haystack import indexes
from generator.models import Template
class TemplateIndex(indexes.RealTimeSearchIndex):
text = indexes.CharField(document=True, use_template=True)
name = indexes.CharField(model_attr='name')
description = indexes.CharField(model_attr='description')
pub_date = indexes.DateTimeField(model_attr='pub_date')
tags = indexes.MultiValueField(indexed=True, stored=True)
def get_model(self):
return Template
def index_queryset(self):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(pub_date__lte=datetime.datetime.now())
I have a model named "Show" and it has a ForeignKey to a model named "Venue." When users add a "Show" I wanted an autocomplete(d) field venue. This solution uses:
- jquery-1.6.1.min.js
- jquery-ui.min.js
models.py
class Venue(models.Model):
name = models.CharField(max_length=255, blank=False, null=False, help_text="Name of the venue")
class Show(models.Model):
date = models.DateTimeField(blank=False, null=False)
venue = models.ForeignKey(Venue)
headliner = models.ForeignKey(Artist, related_name="Headliner")
urls.py
(r'venue_lookup/$','projname.appname.views.venue_lookup'),
views.py
def venue_lookup(request):
venues = Venue.objects.filter(name__istartswith=request.REQUEST['term'])
results = []
for venue in venues:
venue_dict = {'id':venue.id, 'label':venue.name, 'value':venue.name}
results.append(venue_dict)
return HttpResponse(simplejson.dumps(results),mimetype='application/json')
Template:
<html>
<head>
<script type="text/javascript" src="/media/jquery-1.6.2.js"></script>
<script type="text/javascript" src="/media/jquery-ui.js"></script>
<script>
$( "#id_venue" ).autocomplete({
source: "/venue_lookup/",
selectFirst:true,
minLength:2
});
</script>
</head>
<body>
<form method="post" action="/shows/new">
<p><label for="id_venue">Venue</label>
<input type="text" id="id_venue" name="venue" /></p>
<input type="submit" value="done" />
</form>
</body>
</html>
It's easy to get your application to start sending twitter status updates in django.
- Create a twitter account twitter.com
- Create a twitter "application' and get your keys dev.twitter.com/apps
- Click on "settings" and set the access to read and write
- easy_install python-twitter
- Use this template
Whenever you save a "Post" object, the def send_tweet method will attempt to tweet a message containing the name of the object as well as the absolute url.
It's easy to copy and paste urls to share links, but its easier to just click on a button to do it. The way I decided to do it was to write a custom django templatetag. The template tag exists in myproject/myapp/templatetags/sharebuttons.py. You can use the pre-built template here Usage in a template:
{% load sharebuttons %}
{% for p in posts %}
{% sharebutton p "twitter" %}
{% sharebutton p "facebook" %}
{% sharebutton p "linkedin" %}
{% endfor %}
I wanted people to be able to download hatch templates as html files so they can use them for off-line use.
- This should be a single file (no external css, js, or images)
- The server should not have to write any files to it's own disk
- I don't want to write more code than I have to
- The user shouldn't have to right-click "Save As"
First Order of business: Embedding css and javascript in the template itself
I wanted users to only have to download a single file (no external css or javascript) so I looked at the ssi template tag. Create a new url that will be used to download the html file
#urls.py
...
(r'^templates/download/(?P[\w\-]+)/$', 'hatch.eggs.views.download_template' ),
...
Create a view to be used for these requests:
#/hatch/eggs/views.py
...
def download_template(request, slug):
template = Template.objects.get(slug=slug)
template_vars = TemplateVariable.objects.filter(template=template).order_by("id")
return render_to_response("download_template.html",{"template":template, "template_vars":template_vars},context_instance=RequestContext(request))
...
Create a html template and load ssi:
#hatch/templates/download_template.html
<body>
<head>
<style>
{% load ssi from future %}
{% ssi '/var/www/dev.hatchconfigs.com/hatch/media/eggs.css' %}
</style>
</head>
<body>
<script type="text/javascript">
{% ssi '/var/www/dev.hatchconfigs.com/hatch/media/jquery-1.6.1.min.js' %}
</script>
<script type="text/javascript">
{% ssi '/var/www/dev.hatchconfigs.com/hatch/media/hatch.js' %}
</script>
...
</body>
#settings.py:
#this tells django what paths you should expose for server side includes, without it you cannot do ssi.
ALLOWED_INCLUDE_ROOTS= ('/var/www/dev.hatchconfigs.com/hatch/media')
I browsed to my url and confirmed that all css and js were included in the single download_template.html file.
Second: Supplying Content-Type, Content-Disposition http headers with django
After looking at a couple of examples pyText2Pdf, outputting-pdf you see a pattern of using "Content-Disposition." My buddy Ian sent me a link to this article. I came across this snippet which allows you to insert any http header you want via a view decorator. I tried it out and it works... but I wanted something a little more tailored for my needs so I wrote my own decorator:
#eggs/decorators.py
def downloadable(supplied_filename=None):
def _decorator(viewfunc):
def _closure(request, *args, **kwargs):
#if we supply a filename use it,
if supplied_filename:
filename = filename
#otherwise use the slug field from the model being used
else:
if 'slug' in kwargs:
filename = kwargs['slug'] + ".html"
response = viewfunc(request, *args, **kwargs)
#set content-type
response['Content-type']= 'text/html'
#set disposition and filename
response['Content-Disposition']='attachment; filename=%s' % (filename)
return response
return wraps(viewfunc)(_closure)
return _decorator
Third: Tying it all together
- css and js files included in a single htmlm file -- check
- custom decorator to derive filename and set http headers -- check
Now we have to use the decorator in our view:
# hatch/eggs/views.py
from hatch.eggs.decorators import *
...
@downloadable()
def download_template(request, slug):
template = Template.objects.get(slug=slug)
template_vars = TemplateVariable.objects.filter(template=template).order_by("id")
return render_to_response("download_template.html",{"template":template, "template_vars":template_vars},context_instance=RequestContext(request))
...
Now whenever someone browses to /templates/download/some_slug/ the browser will ask if you want to save the file named some_slug.html, yay!
I wrote a django app which uses tratto to fetch router configurations. These configurations are stored in a TextField defined in a model named "Output." I wanted to display this readonly field in a preformatted block. At first I used fieldsets and defined a specific class to the fieldset to solve the problem using css. I didn't like what I saw so I decided to write a simple widget which would simply render my field's value wrapped with a "pre" tag.
/var/www/<fqdn>/compass/tratto/widgets.py
from django import forms
from django.utils.safestring import mark_safe
class PreformattedTextWidget(forms.Widget):
def render(self, name, value, attrs=None):
return mark_safe("<br/><pre>%s </pre>" %(value))
/var/www/<fqdn>/compass/tratto/admin.py
from django.contrib import admin
from django.db import models
from tratto.models import *
from tratto.widgets import *
class OutputAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': PreformattedTextWidget},
}
This essentially overrides the default widget for TextField in my Output model and uses the PreformattedTextWidget which simply prints the value wrapped in pre tags
Model:
class Command(models.Model):
command = models.TextField(('Command(s)'))
description = models.TextField(blank=True, null=True)
os = models.ForeignKey(OperatingSystem)
def __unicode__(self):
return self.command
Admin:
class CommandAdmin(admin.ModelAdmin):
list_display= ['command','description','os']
readonly_fields=[]
fields =['command','description','os']
def get_readonly_fields(self, request, obj=None):
if obj is None:
'''obj has not been created yet'''
return self.readonly_fields
else:
'''we already know about this object make command readonly'''
return self.readonly_fields + ['command']
Documentation: Django Assignment Tags
/project/myapp/templatetags/app_admin_tags.py:
from django import template
from myapp.models import *
@register.assignment_tag(name="object_attrs")
def object_attrs(obj):
obj_dict ={}
for attr in obj._meta.get_all_field_names():
obj_dict[attr] = obj.__getattribute__(attr)
return obj_dict
Template:
{% load app_admin_tags %}
{% for obj in objects %}
{% object_attrs obj as obj_dict %}
{% for key,value in obj_dict.items %}
{{key}}: {{ value }}
{% endfor %}
{% endfor %}
/project/myapp/myapp_admin_tags.py:
from django import template
from django.core.urlresolvers import reverse
register = template.Library()
@register.tag(name="make_table")
def do_make_table(parser, token):
try:
# split_contents() knows not to split quoted strings.
tag_name, object_list, caption, field_list = token.split_contents()
field_list = field_list.replace('\"','')
field_list = field_list.split(",")
caption = caption.replace('\"','')
except ValueError:
raise template.TemplateSyntaxError("%r tag requires exactly three arguments" % token.contents.split()[0])
return MakeTable(object_list,caption, field_list)
class MakeTable(template.Node):
def __init__(self, object_list,caption, field_list):
self.object_list = template.Variable(object_list )
self.field_list = field_list
self.caption = caption
def render(self, context):
try:
caption_html="<caption>%s</caption>" %( self.caption)
object_list = self.object_list.resolve(context)
th_fields = self.field_list
th_html=""
for th in th_fields:
th_html += "<th>%s</th>" %(th.replace("_"," ").capitalize())
thead = "<thead><tr>%s</tr></thead>" %(th_html)
tr_html=""
for obj in object_list:
td_html=""
for field in self.field_list:
if field == th_fields[0]: #is first col in list
url = reverse('admin:%s_%s_change' %(obj._meta.app_label,obj.__class__.__name__.lower()), args=(obj.id,) )
td_html += "<td><a href='%s'>%s</a></td>" %(url,obj.__getattribute__(field.replace("'","")))
else:
td_html += "<td>%s</td>" %(obj.__getattribute__(field.replace("'","")))
tr_html += "<tr>%s</tr>" % (td_html)
table_html = "<table>%s %s %s</table>" %(caption_html, thead, tr_html)
return table_html
except template.VariableDoesNotExist:
return ''
Template:
{% make_table changes "Recent Changes" "updated_on,job,node,performed_command,successful" %}
Where outputs is a list of "Change" objects, "Recent Changes" is what I want the table caption to be, then a list of all the fields I want in the table.

So this is a little more flexible than my last post. It's pretty much the same but it uses an html template so you have more control over the appearance and you can use the built-in filters such as "date."
from django import template
from django.core.urlresolvers import reverse
import datetime
@register.tag('make_table')
def do_make_table(parser, token):
try:
# split_contents() knows not to split quoted strings.
tag_name, object_list, caption, field_list = token.split_contents()
field_list = field_list.replace('\"','')
field_list = field_list.split(",")
caption = caption.replace('\"','')
except ValueError:
raise template.TemplateSyntaxError("%r tag requires exactly three arguments" % token.contents.split()[0])
return MakeTable(object_list,caption, field_list)
class MakeTable(template.Node):
def __init__(self, object_list,caption, field_list):
self.object_list = template.Variable(object_list )
self.field_list = field_list
self.caption = caption
def render(self, context):
try:
object_list = self.object_list.resolve(context)
if object_list.count() < 1:
return ''
if self.field_list[0] == "*" and object_list:
self.field_list = object_list[0]._meta.get_all_field_names()
th_fields=[]
for field in self.field_list:
th_fields.append(field.replace("_"," "))
tr_rows =[]
for obj in object_list:
td_list=[]
for field in self.field_list:
this_field={}
value = obj.__getattribute__(field.replace("'",""))
if isinstance(value,datetime.datetime):
field_type="date"
else:
field_type="text"
if field == self.field_list[0]:
key = True
url = reverse('admin:%s_%s_change' %(obj._meta.app_label,obj.__class__.__name__.lower()), args=(obj.id,) )
else:
url = None
key = False
this_field = {'type':field_type,'value':value,'key':key,'url':url}
td_list.append(this_field)
tr_rows.append(td_list)
t = template.loader.get_template('admin/ncm/make_table.html')
c = template.Context({'caption':self.caption,'th_fields':th_fields,'tr_rows':tr_rows})
rendered = t.render(c)
return rendered
except template.VariableDoesNotExist:
return ''
admin/templates/ncm/make_table.html:
<table>
<caption>{{caption|title}}</caption>
<thead>
<tr>
{% for th in th_fields %}
<th>{{th|title}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for tr in tr_rows %}
<tr>
{% for field in tr %}
<td>
{% if field.key %}
<a href="{{field.url}}">
{% endif %}
{% if field.type == "date" %}
{{field.value|date:"F d, Y f a"}}
{% else %}
{{field.value|truncatechars:30}}
{% endif %}
{% if field.key %}
</a>
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Some django template: where outputs is a list of objects "Recent Outputs" is the caption, and a list of model fields to put in the table
{% load spur_admin_tags %}
<div class="module">
{% make_table outputs "Recent Outputs" "updated_on,job,node,performed_command,successful" %}
</div>

I recenly wrote a django app which needed to store regex strings in a model. Since I couldn't find a way to store raw strings in models I wrote a function to convert unicode or string into string literals.
def to_raw_string(s):
if isinstance(s,str):
s = s.encode('string-escape')
if isinstance(s,unicode):
s = s.encode('unicode-escape')
return s
Here is my pre-defined code called "Systems.py" as you can see I create a dictionary at the end of this to link display names to classes. This code is part of the meat-and-potatoes of my web app and instead of creating a model for these I want them to be defined in the actual code. I don't want to access the database every time I need to reference these and I also want this code to be portable in the means that you can use it in a shell as well as the web app.
class OperatingSystem(object):
ESCALATE_COMMAND=''
PAGINATES =False
VERSION =''
PROMPTLINE =''
class CiscoIOS(OperatingSystem):
'''cisco ios'''
PROMPTLINE = r'[-\w]+[>#]'
GET_CONFIG ='show running-config'
PAGINATES =True
VERSION ='show version'
DISABLE_PAGINATION = 'terminal length 0'
ESCALATE_COMMAND='enable'
class CiscoWebNS(OperatingSystem):
'''cisco webns css 11500'''
PROMPTLINE ="#"
GET_CONFIG ='show running config'
PAGINATES =True
DISABLE_PAGINATION = 'terminal length 65000'
class AppleOSX(OperatingSystem):
'''apple OSX defaults'''
PROMPTLINE = r'[-\w]+[$#]'
VERSION ="uname -a"
PRIVILEGE ="sudo su"
class OpenBSD(OperatingSystem):
'''OpenBSD defaults'''
PROMPTLINE = r'[$#]'
VERSION ="uname -a"
PRIVILEGE ="sudo su"
class SecureComputingSidewinder(OperatingSystem):
'''sidewinder configs'''
PROMPTLINE ='{}'
PRIVILEGE ='srole'
GET_CONFIG ="cf acl query"
class ArubaOS(OperatingSystem):
'''aruba configs'''
PROMPTLINE ='#'
PAGINATES =True
DISABLE_PAGINATION = 'terminal length 0'
GET_CONFIG ="show run"
OperatingSystems = {
'IOS': CiscoIOS,
'WebNS': CiscoWebNS,
'OSX': AppleOSX,
'SOS': SecureComputingSidewinder,
'AOS': ArubaOS,
'OBSD': OpenBSD,
}
In my django app I have a model like so:
os_list = ((k,k) for k in Systems.OperatingSystems.iterkeys())
class Node(models.Model):
name = models.CharField(max_length=100)
ip = models.IPAddressField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
os = models.CharField(choices=os_list,max_length=6, null=True, blank=True)
transport = models.CharField(choices=transports, max_length=10)
credentials = models.ForeignKey(Credential, blank=True, null=True)
escalation_credentials = models.ForeignKey(Credential, blank=True, null=True, help_text="root or enable passwords if needed", related_name="enable_password" )
def get_ip(self):
return self.ip
def __unicode__(self):
return self.name + " - " + str(self.ip)
Meaningful snippet:
from ncm.management.commands import Systems
os_list = ((k,k) for k in Systems.OperatingSystems.iterkeys())
This iterates over my "OperatingSystems" dictionary's keys and constructs a tuple of (key,key) so that I can use it as a flat_choice for my os field.
This is an ultra-hacky way to create initial_data fixtures for django admin's Sites.site. Create a variable in settings.py such as "FQDN" then create a dictionary with all the values and wrap it with a list, import json and dump the list into json and write it to app_name/fixtures/initial_data.json
settings.py:
#ADD your own variable
FQDN="www.whateversite.com"
full_path = 'path/to/project/project_name/app_name/fixtures/initial_data.json'
print full_path
try:
with open(full_path) as f: pass
except IOError as e:
print str(e)
site_fixture_dict = {}
site_fixture_dict['pk']=1
site_fixture_dict['model']="sites.site"
site_fixture_dict['fields']={'name':FQDN,'domain':FQDN}
site_fixture_list = [site_fixture_dict]
import json
json = json.dumps(site_fixture_list)
f = open(full_path,'w')
f.write(json)
f.close()
Now any time you run ./manage.py syncdb a fixture will be created then loaded into the database
Spur is a web based network configuration manager. It allows you to ssh or telnet to any device and run commands through a web front-end.The results of these commands are stored and can be diff'd. You can get alerted whenever a diff is found. You can extend Spur's capabilities by writing your own modules for different types of equipment.
Spur is comprised of:
- Tratto - a ssh/telenet framework built on-top of pexpect
- A custom written "cron" which allows you to create and schedule repetitive tasks
- Customized django skin
- Cisco syntax highlighting via syntax-highlighter
This project is in beta, I need people to help test. I have not used spur to configure any network equipment as of right now.
System Requirements
- Python
- Django 1.4+
- Sqlite, mysql, posgres
which python # find out if you have python installed
#django installation
wget http://www.djangoproject.com/m/releases/1.4/Django-1.4.1.tar.gz
tar xzvf Django-1.4.1.tar.gz
cd Django-1.4.1
sudo python setup.py install
#sqlite installation
sudo apt-get install sqlite
Python Requirements
- django-mptt
- pexpect
- croniter
- pytz
sudo easy_install django-mptt
sudo easy_install pexpect
sudo easy_install croniter
sudo easy_install pytz
Spur Installation
git clone https://github.com/akonkol/spur.git
cd spur
#edit this file to match your enviornment
vi spur/spur_settings.py
#create an admin user
python manage.py syncdb
python manage.py runserver 0.0.0.0:8000
#Create a cronjob for spur
crontab -e
* * * * * /path/to/spur/manage.py spur-cron
Browse to spur http://your_fqdn_or_ip:8000
Thanks for checking it out.
I wrote hatch a few years ago to make cookie cutter network config templates. One thing I've wanted to implement for a while is a DSL for use in hatch. I've experimented with jscc and more recently with peg.js. While writing grammar for peg.js I said to myself "it would be great if I could used Django's template system and filters without re-inventing the wheel."
So I started experimenting and found out its pretty easy to do. A little more tinkering and I could possibly replace hatch's mechanics with Django's builtin template, tag, and filter code.
#!/usr/bin/python
from django.conf import settings
from django import template
settings.configure(DEBUG=True, TEMPLATE_DEBUG=True)
#https://github.com/django/django/blob/master/django/template/__init__.py
s = u'conf t\n ip address {{ip_address}} {{subnet_mask}} \n end \n write'
t = template.Template(s)
c = template.Context({'ip_address': '192.168.1.1','subnet_mask':'255.255.255.0'})
rendered = t.render(c)
print rendered
print "----------------------------------"
s = u'conf t\n ip address 10.{{site_code}}.1.1 {{subnet_mask}} \n end \n write'
t = template.Template(s)
c = template.Context({'site_code': '66','subnet_mask':'255.255.255.0'})
rendered = t.render(c)
print rendered
print "----------------------------------"
s = u'conf t\n {% if site_code == 66 %}snmp-server location Sydney{% endif%}'
t = template.Template(s)
c = template.Context({'site_code': 66})
rendered = t.render(c)
print rendered
akonkol@dev:~/Code/messy$ ./temp_hack.py
conf t
ip address 192.168.1.1 255.255.255.0
end
write
----------------------------------
conf t
ip address 10.66.1.1 255.255.255.0
end
write
----------------------------------
conf t
snmp-server location Sydney