Archive for Web Development

Adding additional links to Django’s Admin

If you’re like me, you’d like to add some new links to one of the Django admin lists (perhaps to delete right from the list or to direct a user to a custom made view).

Here’s the relevant code:

To your model, add:

def some_name(self):
return '<a href="/some/admin/url/here/%s/">Link Name</a>' % self.id
some_name.allow_tags = True #this is to allow HTML tags.
some_name.short_description = 'Table Header Name here'

And then just add “some_name” to your “class Admin” in the “list_display” list. Nice and neat.

Comments off

Safari and Django Redirects

I was working on a Django Project (http://naturalareas.saleient.com/) and I was having trouble with people visiting the site with Mac’s Safari. As it turns out, a shortcut I was using was causing the problem. I was using HttpResponseRedirect(“/page-name/”) and apparently Safari doesn’t like this. It’s actually looking for the entire URL. So I had to change my code to HttpResponseRedirect(“http://naturalareas.saleient.com/page-name/”) and it worked.

Comments off

TeamRemind.com Beta Launch

Yup, we’re finally ready to show this guy off a little bit. The look and feel of it is not set yet and we’re still finalizing a few features but it’s good enough to show a few people and have some people test it out.

We’re already getting some good feedback.

FYI – If anyone out there is building a website, I have a few suggestions. First, design your code to be as simple and clean as you can get. TeamRemind.com flies off the server because of it’s slim HTML code and external CSS and Javascript (which are cached on most browsers). Also, it will be easier to maintain down the road.

Check it out at www.teamremind.com

Comments off

Code Search Engine – Krugle

Bad name but a great service for programmers.

http://www.krugle.com/

Comments off

Work life update

Here’s a few cool projects that I’ve worked on over the past couple years. Enjoy.

http://www.nothingbutnets.net
(I did a bunch of the set up on this site. The design was created by a company in Vancouver)

http://naturalareas.saleient.com/
This site is a survey for the city of Edmonton to see what the citizens think of the local natural areas. This was very successful and could lead to some more work with the city in the future. I worked with Mike Evans (http://www.teleologic.ca/) and James Mireau (http://www.taskone.com/) on this. Mike did all the communications work and James put together the design. I created the survey and did the statistical analysis. The survey is just one part of the project.

http://www.allaboutelectrical.com/
This site is just starting out but it’s going to be cool. Ask questions about electrical matters.

http://www.mbveneer.com/
I built all the back end systems. The design was done by a company in Calgary. In particular, check out http://www.mbveneer.com/designzone-covermyworld.cfm and try building a project.

http://www.albertasoccer.com/
I’m currently working on trying to get them to update the site. It could look so much better.

The land developer’s project management software is at http://www.aceraprojects.com/ and it’s for Acera (www.acera.ca). There’s a demo available at http://pm.pivotib.com/ but it really needs a bit of an introduction before you can wade into it.

Of course there’s also my other sites like www.saleient.com and www.conflux.ca

Now, if you’re interested in seeing the cools stuff that’s emerging on the internet you could visit these sites:
http://www.techcrunch.com/
http://digg.com/

A couple blogs that I check frequently:
http://blog.guykawasaki.com/
http://headrush.typepad.com/creating_passionate_users/
http://www.goodexperience.com/index.php
http://www.37signals.com/svn/

Some of my friends are doing cool things too:
http://www.markwells.ca/ – Mark writes on Alberta Politics and other miscellaneous topics.
http://www.1024media.com/ – My friend Branden is an expert at getting web traffic to his clients’ sites.
http://www.liftinteractive.com/ – These guys are upstairs in my building. They’re releasing a new product, http://getparade.com/, very soon.
http://inviteright.com/ – These guys are also in the building. Online event planning.
http://www.fissionmediagroup.com/ – These guys are in the building as well. I’m working on a upcoming project with them.

Comments off

Django Newforms

Binding a form to a model instanceDjango’s newforms module provides the helper method ‘form_for_instance’. The method will return a Form similar to the one returned by form_for_model but the initial data will be populated by the instance’s data. The form will have a ‘save’ method which will save changes to the instance to the database (unless it is passed the commit=False argument) and will return the instance itself.

Sometimes, however, it is desirable to use fields different from the default. In order to bind a form to an instance one will have to provide __init__ and save methods.

The __init__ method should be defined as follows:


def __init__(self, data=None, auto_id='id_%s', prefix=None,
initial=None, instance=None):
  if instance is not None:
    self.instance = instance
    new_data = {}
    # Populate new_data using 'instance'
    # ...
    data = new_data
  else:
    self.instance = None
super(MyForm, self).__init__(data, auto_id, prefix, initial)

The __init__ method will save the original instance in self.instance and pass the data it contains to the superclass (most likely forms.Form). The bound form will be created with MyForm(instance=MyInstance). To use the form for creating new instances it can be created with MyForm(request.POST).

The save method will look similar to the following:
def save(self, commit=True):
  if self.instance is not None:
    instance = self.instance
  else:
    instance = InstanceModel()

# Construct the instance below using self.clean_data
# Using self.clean_data ensures everything is validated.
# ...

if commit:
  instance.save()
return instance

It should be noted that one will not be able to save ManyToMany data without saving the instance first. If the model contains M2M fields then commit=False will not make any sense.

Views

Your add+edit view should look something like the following:

def add_edit_model(request, id=None):
if id is not None:
instance = MyModel.objects.get(id=id)
InstanceForm = MyForm(instance=instance)
else:
InstanceForm = MyForm()

if request.POST:
form = InstanceForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(‘/whatever/url/’)

return render_to_response(‘template.html’, {‘form’: InstanceForm})

Comments off

Django Quickies

Debugging in templates

<pre>{% debug %}</pre>

<pre>errors
{{ form.error_dict|pprint }}</pre>

<pre>data
{{ form.data|pprint }}</pre>

Example of Edit Inline

models.py

class Poll(models.Model):
    question = models.CharField(maxlength = 200)

class Choice(models.Model):
    poll = models.ForeignKey(Poll, edit_inline=models.STACKED, num_in_admin=3)
    choice = models.CharField(maxlength = 200, core = True)
    votes = models.IntegerField(core = True)

urls.py

urlpatterns = patterns('',
    [...]
    (r'^poll_update/(?P<object_id>d+)/$', 'django.views.generic.create_update.update_object', {'model': Poll})
)

templates/myapp/pollform.html

{% extends "base.html" %}
{% block content %}

<pre>errors
{{ form.error_dict|pprint }}</pre>
<pre>data
{{ form.data|pprint }}</pre>

<p>Today's question is: <em>{{ object.question }}</em></p>

<form method="POST" action="./">

     <label for="id_question">Question:</label>{{ form.question }}

       {% for the_choice in form.choice %}
        {{ the_choice.id }}

        <TABLE>
        <TH><label for="id_choice.{{ forloop.counter0 }}.choice">Choice
        <TD>{{ the_choice.choice }}
        <TH><label for="id_votes.{{ forloop.counter0 }}.votes">Votes
        <TD>{{ the_choice.votes }}
        </TABLE>
   {% endfor %}

    <input type="submit" />
</form>

{% endblock %}

Send Emails

views.py

from django.core.mail import send_mail

send_mail('Subject here', 'Here is the message.', 'from@domain.com',
    ['to@domain.com'], fail_silently=False)

settings.py

EMAIL_HOST = 'domain.com'
EMAIL_PORT = '25'
EMAIL_HOST_USER = 'username'
EMAIL_HOST_PASSWORD = 'xxxxxxxx'

Generate RSS

from django.conf import settings
from django.utils import feedgenerator
from nm.models import Newsitem
import os

def generate_rss(self):

    file_name = "latest_news.rss"
    file_path = os.sep.join([settings.MEDIA_ROOT, file_name])
    file_url = os.sep.join([settings.MEDIA_URL, "site_media", file_name])

    feed = feedgenerator.Rss201rev2Feed(
        title=u"Newsmemory",
        link=file_url,
        description=u"Dernières nouvelles",
        language=u"fr",
    )

    qs = Newsitem.objects.select_related().filter(...)[:50]

    for r in qs:
        text = "<br />".join([r.source.name, "%s" % r.time, r.text])
        feed.add_item(title=r.title, link=r.get_absolute_url(), description="")

    fp = open(file_path, 'w')
    feed.write(fp, 'utf-8')
    fp.close()

Reuse Login / Logout

settings.py

INSTALLED_APPS = (
    'django.contrib.auth',
    [...]
)

urls.py

 (r'^accounts/login/$', 'django.contrib.auth.views.login'),
 (r'^accounts/logout/$', 'django.contrib.auth.views.logout'),

app_name/urls.py

(r'^accounts/profile/$', 'projectname.invoice.views.index'), # default page after login

templates/appname/registration/loggedout.html

templates/app_name/registration/loggin.html

{% block content %}

<div id="box"><h4>Login</h4></div>

{% if form.has_errors %}
<div id="alert">
    <p>Your username and password didn't match. Please try again.</p>
</div>
{% endif %}

{% if user.is_authenticated %}
<div id="alert">
    <p>You are already logged in as "{{ user }}".</p>
</div>
{% endif %}

<form method="post" action=".">
<P>
<table>
<tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
<tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>
</table>
</P>
<p>
<input type="submit" value="Login" />
<input type="hidden" name="next" value="{{ next }}" />
</p>
</form>

{% endblock %}

Creating and Using Custom Filters

projectname/invoice/templatetags/

__init__.py
custom_filters.py

projectname/invoice/templatetags/custom_filters.py

from django import template
from django.conf import settings

def nop(value):
    return value[3:-4]

register = template.Library()
register.filter('nop', nop)

projectname/settings.py

INSTALLED_APPS = (
    'projectname.invoice'
)

projectname/templates/invoice/customer_detail.html

{% load custom_filters %}
{{ object.address|linebreaks|nop }}

Reuse Django Admin Widgets and Graphics

urls.py

urlpatterns = patterns('',
    [...]
     (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', {'packages': 'django.conf'}),
)

settings.py

ADMIN_MEDIA_PREFIX = '/media/'

template file

<script type="text/javascript" src="/jsi18n/"></script>
<script type="text/javascript" src="/media/js/core.js"></script>
<script type="text/javascript" src="/media/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="/media/js/calendar.js"></script>
<script type="text/javascript" src="/media/js/admin/DateTimeShortcuts.js"></script>

<img src="/media/img/admin/icon_changelink.gif">

Comments off

wikiCalc goes 1.0

This might make sense to include within TeamRemind.com. Potentially, we could make this available to teams so that they could post and keep track of scores or statistics. This might also be nice for Leagues to use to post standings, statistics or even a schedule. WikiCalc is written in Perl and released under the GPL 2.0 license.

Comments (1)

Online Learning

Taken from an article at Linux.com

Managing Moodle

Moodle system administrators manage their CMS via a Web interface that includes control over nearly every aspect of the site. Site functionality includes a site-level calendar, emailing options, log and report analysis, and search engine interoperability. The interfaces are easy to use and generally come equipped with help buttons throughout the pages.

Moodle has addressed security issues as well, albeit in a minimalist fashion. Moodle uses SSL for logins; however, the sessions following the logins are not encrypted. Moodle also includes a GUI-based log viewing system as part of the administrator tools. It allows administrators to filter logs based on individual courses, users, activities, actions, and time. Filtered reports cannot be exported, but administrators can save or print the displayed HTML pages.

Tips for administering Moodle sites and courses

I have installed Moodle dozens of times and used it to teach language and technology courses. I also train teachers to use Moodle and assist them during their initial courses. Here are some tips for Moodle administrators and teachers.

As with all new applications, administrators should make preparations before installing Moodle. The following checklist might help:

1. Ensure the server on which you plan to install the software has all of the required and optional components installed. For example:

Verify the required server applications — Web, database, and messaging — are operational.

Install a spell checker (such as Aspell), a zip and unzip program, and an anti-virus utility (e.g. ClamAV) into the main server so Moodle can use them.

Install the mbstring and iconv PHP extensions, and set the maximum upload size in php.ini.

2. Set email policies. What mail router will this server use? Will Moodle users be required to use school email? What character set will outgoing mail use?

3. Select an authentication method. Current options include PAM, LDAP, POP3, IMAP, NNTP, CAS, and FirstClass servers. Email-based authentication is also available. If your school already has an existing authentication method for another system, Moodle may be able to tap into it.

4. Discuss and decide what Moodle options to turn on or off, such as RSS feeds, Google searchability, and podcasts.

5. Establish regulations regarding user authority.

Define system roles. Moodle defines users based on preset roles (system administrator, course creator, teacher, non-editing teacher, student, and guest) Decide the appropriate authority for each user.

Determine who is allowed to view personal profile data — anyone, guests, schoolmates, classmates, etc. Profile information includes basic information like name, email, and chat IDs. Privacy concerns may encourage schools to limit access.

6. Create usage, privacy, and security policies to protect the school and the users from inappropriate site activity.

7. Establish a system for uploading students and users. Moodle allows students to be uploaded via CSV files. The system administrator, working in conjunction with the academic office, can develop scripts to auto upload students and users from an existing school database to Moodle’s database. Instituting a script-based user upload will greatly reduce headaches.

Tips for e-learning course developers

Teachers new to e-learning and course development will find many tips online regarding e-learning course development and use. The following tips focus more on Moodle courses.

1. Plan before you build. After the creation of a default course, you can begin adding content. I recommend having a syllabus that includes objectives, a grade system, and a schedule. These three components of your paper-based syllabus are easily imported into your Moodle course.

2. Set up grade categories at the beginning of the course. Grade categories determine how grades are formulated. For example, I have a course that includes four areas of graded activities — homework (25%), quizzes (20%), tests (25%), and projects (30%). These areas are the categories into which I input the grades for my graded activities. Once the categories are created, any new activity I add to the course can automatically be placed in the proper category. Furthermore, students will be able to see their grades for each activity and see their total grade as the course progresses. If the categories are not set up in advance, students cannot determine their current grade status.

3. Start small and build up. Since Moodle has many functions, it is a good to begin with simple tools. For example, begin by uploading the syllabus, which Moodle calls a resource. Put all of your paper resources on your course schedule in the appropriate week you plan on using them. If you place resources in your course, students won’t need to come to you for a lost paper — they can get it for themselves.

Regarding resources, I recommend using platform-independent file formats, so that any user can open your resource. I recommend Adobe Acrobat files or HTML for text information, since every computer can read them. Avoid Microsoft Word and PowerPoint files. For presentations, convert the PowerPoint to HTML or Flash.

4. Begin by using tools that are easy to set up and can be used quickly. I recommend using the assignments, forums, and journals. Assignments can be files that are uploaded, such as a book report, or offline activities. For example, when I first started using Moodle, I gave quizzes on paper and made an offline assignment into which I placed the quiz results. Students could then see their quiz grades without having to wait until class time.

Forums allow students to post messages and respond to other posted messages. I use forums to extend a classroom discussion. Journals are comments that only the teacher can read. I use these for reports and some written homework.

5. Hide activities you are developing but not ready to present to your students. Each activity has an eye icon that closes when it is hidden.

Comments off

Web 2.0 Pessimism

Here’s a less glossy look at Web 2.0 for people thinking of getting into it.

Comments off